# 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
