Yield Module

High-Level Overview

This contract manages the blending of various Real-World Asset (RWA) interest rates and TVL vault strategies in the treasury. The contract calculates a blended weekly interest rate and maintains a P90 (90th percentile) rate that can be used by the distribution module for token emissions calculations.

The core features of this contract include:

  • Interest Rate Management: Manages yield sources with either Chainlink oracle feeds or manual interest rates

  • Blended Rate Calculation: Calculates a weighted average of interest rates based on asset values in treasuries

  • P90 Rate Management: Maintains a configurable P90 interest rate for distribution calculations

  • Treasury Management: Tracks multiple treasury addresses for asset balance calculations

  • Access Control: Each functionality is controlled by specific roles with minimal required permissions

Contract Summary

Inherited Contracts

  • PausableUpgradeable: Allows contract execution to be paused/unpaused by authorized role

  • IYieldModule: Interface defining all public/external functions

Functionality Description

Public/External Functions

Administrative Functions:

  • initialize: Initializes contract with registry address and sets initial max data age

  • pause: Pauses contract operations (PAUSING_CONTRACTS_ROLE only)

  • unpause: Unpauses contract operations (DEFAULT_ADMIN_ROLE only)

Yield Source Management:

  • addYieldSourceWithFeed: Adds yield source with Chainlink oracle feed (YIELD_MODULE_TOKENOMICS_OPERATOR_ROLE only)

  • addYieldSourceWithWeeklyInterest: Adds yield source with manual weekly interest rate (YIELD_MODULE_TOKENOMICS_OPERATOR_ROLE only)

  • removeYieldSource: Removes a yield source (YIELD_MODULE_SUPER_ADMIN_ROLE only)

  • updateInterestRate: Updates manual interest rate for a new one. This function will override the feed address if it exists (YIELD_MODULE_UPDATER_ROLE only)

  • updateFeed: Updates Chainlink feed address for a new fee address (YIELD_MODULE_UPDATER_ROLE only)

Treasury Management:

  • addTreasury: Adds a treasury address for asset balance tracking (YIELD_MODULE_SUPER_ADMIN_ROLE only)

  • removeTreasury: Removes a treasury address (YIELD_MODULE_SUPER_ADMIN_ROLE only)

Configuration:

  • setMaxDataAge: Sets maximum allowed age for oracle data (YIELD_MODULE_MAX_DATA_AGE_ROLE only)

  • setP90InterestRate: Sets P90 interest rate value (YIELD_MODULE_P90_INTEREST_ROLE only)

View Functions:

  • getBlendedWeeklyInterest: Calculates current blended weekly interest rate

  • getP90InterestRate: Returns current P90 interest rate

  • getYieldSource: Returns data for specific yield source

  • getYieldSourceCount: Returns total number of yield sources

  • getAllYieldSourceData: Returns data for all yield sources

  • getTreasuryCount: Returns number of tracked treasuries

  • getAllTreasury: Returns all treasury addresses

Functionality Breakdown

Yield Source Management

  • Each yield source can use either a Chainlink oracle feed or manual interest rate

  • Oracle feeds must provide valid, recent data within maxDataAge

  • Manual rates are validated to be within acceptable bounds

  • Interest rates are expressed in basis points (1 = 0.01%)

Blended Rate Calculation

The getBlendedWeeklyInterest() function calculates a weighted average of all RWA interest rates based on their USD value in the treasury. Here's the detailed calculation process:

  1. Asset Value Calculation (in USD) For each RWA token:

    assetValue = price * balance / (10 ^ decimals)

    where:

    • price is obtained from the oracle for that RWA

    • balance is the sum of the RWA token balance across all registered treasuries

    • decimals is the token's decimal places

  2. Weighted Interest Rate For each RWA:

    weightedSum += rate * assetValue
    totalValue += assetValue

    where:

    • rate is either:

      • The latest valid rate from the Chainlink oracle feed if configured

      • The manually set weeklyInterestBps if no feed is configured

    • Oracle data must be fresher than maxDataAge to be considered valid

  3. Final Blended Rate

    blendedRate = totalValue > 0 ? weightedSum / totalValue : 0

    The final rate is rounded down and must be less than BASIS_POINT_BASE (10000)

Constants

  • YIELD_MODULE_TOKENOMICS_OPERATOR_ROLE: Role for adding yield sources

  • YIELD_MODULE_SUPER_ADMIN_ROLE: Role for removing yield sources and treasury management

  • YIELD_MODULE_P90_INTEREST_ROLE: Role for setting P90 interest rate

  • YIELD_MODULE_MAX_DATA_AGE_ROLE: Role for setting maximum data age

  • YIELD_MODULE_UPDATER_ROLE: Role for updating yield sources

  • INITIAL_YIELD_MODULE_MAX_DATA_AGE: Default maximum age for oracle data (14 days)

  • DEFAULT_YIELD_FEED_RATE: Default rate for new oracle feeds

  • BASIS_POINT_BASE: Base for interest rate calculations (10000 = 100%)

Safeguard Implementation

Access Control

  • Role-based access control for all administrative functions

  • Specific roles for different aspects of yield management

  • Minimal permissions principle applied to role assignments

Pausability

  • Contract can be paused by PAUSING_CONTRACTS_ROLE

  • Only DEFAULT_ADMIN_ROLE can unpause

  • Protects against emergencies or discovered vulnerabilities

Data Validation

  • Oracle data freshness checks

  • Interest rate bounds validation

  • Duplicate treasury prevention

  • Null address checks

Oracle Safety

  • Maximum data age enforcement

  • Oracle interface validation

  • Fallback to manual rates if needed

Last updated

Was this helpful?