> For the complete documentation index, see [llms.txt](https://tech.usual.money/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tech.usual.money/smart-contracts/protocol-contracts/usual/usual-distribution/yield-module.md).

# 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


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://tech.usual.money/smart-contracts/protocol-contracts/usual/usual-distribution/yield-module.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
