# Distributor

## Introduction

The `Distributor` contract acts as the central coordination layer for distributing rewards to `DepositPool` instances across various reward pools. It is responsible for aggregating yield across strategies, calculating proportional rewards, managing price feeds via Chainlink, and forwarding yield to the L1 bridge contract for minting rewards on L2. This contract ensures that yield-based reward emissions are fairly and accurately routed according to pool performance.

### Key Responsibilities

1. Reward Aggregation and Distribution
   * Coordinates reward distribution across multiple `DepositPool` instances per `rewardPoolIndex`.
   * Aggregates token yield (e.g., from AAVE strategies) and calculates share per `DepositPool`.
   * Tracks last reward calculation time and ensures time-based emission updates.
2. `DepositPool` Registry Management
   * Supports adding deposit pools to a reward pool, with specific strategy (AAVE or NO\_YIELD...).
   * Ensures compatibility with registered reward pools via `RewardPool` contract validation.
   * Maintains mappings of pool configuration and yield tracking.
   * Automatically updates Chainlink token prices during reward distribution.
3. Chainlink Price Feed Integration
   * Uses a `ChainLinkDataConsumer` to fetch and store up-to-date prices for staked tokens.
   * Ensures rewards are calculated in terms of value (`price * yield`), not just raw token amounts.
4. Cross-Chain Yield and Reward Handling
   * Interfaces with `L1SenderV2` to send messages for reward minting on L2.
   * Enables yield withdrawal to the L1 bridge.
   * Can transfer undistributed rewards in edge cases (e.g., zero yield scenario).

## Storage

### depositPools

Maps reward pool index and deposit pool address to the deposit pool configuration. `depositPools[<rewardPoolIndex]][<DepositPool>]`.

```solidity
mapping(uint256 => mapping(address => DepositPool)) public depositPools
struct DepositPool {
  address token;
  string chainLinkPath;
  uint256 tokenPrice;
  uint256 deposited;
  uint256 lastUnderlyingBalance;
  Strategy strategy;
  address aToken;
  bool isExist;
}

/**
 * @notice The Yield strategy.
 * NONE - for tokens without yield strategy (stETH).
 * NO_YIELD - for virtual tokens in the private buckets.
 * AAVE - fot tokens with Aave yield strategy.
 */
enum Strategy {
  NONE,
  NO_YIELD,
  AAVE
}
```

| Name                    | Description                                                              |
| ----------------------- | ------------------------------------------------------------------------ |
| `token`                 | The yield token (stETH, wBTC...).                                        |
| `chainLinkPath`         | The path from the `ChainLinkDataConsumer`.                               |
| `tokenPrice`            | The last calculated token price. Used for internal calculations. Wei.    |
| `deposited`             | The deposited `token` amount. Wei.                                       |
| `lastUnderlyingBalance` | The last calculated balance that include the `yield`. Wei.               |
| `strategy`              | The `Strategy`.                                                          |
| `aToken`                | The `aToken` address for the pools with `AAVE` strategy. Zero for other. |
| `isExist`               | The existed flag. Should be true id deposit pool added.                  |

### isDepositTokenAdded

Return `true` when `DepositPool` address added to this contract.

```solidity
mapping(address => bool) public isDepositTokenAdded;
```

### distributedRewards

Tracks how much MOR reward has been distributed to each `DepositPool`. Wei. `distributedRewards[<rewardPoolIndex]][<DepositPool>]`.

```solidity
mapping(uint256 => mapping(address => uint256)) public distributedReward;
```

### depositPoolAddresses

Stores all deposit pool addresses registered for a given reward pool.

```solidity
mapping(uint256 => address[]) public depositPoolAddresses;
```

### rewardPoolLastCalculatedTimestamp

Timestamp in seconds of last reward distribution for each reward pool.

```solidity
mapping(uint256 => uint128) public rewardPoolLastCalculatedTimestamp;
```

### isPrivateDepositPoolAdded

Flags whether a private deposit pool has been added for the given reward pool index.

```solidity
mapping(uint256 => bool) public isPrivateDepositPoolAdded
```

### chainLinkDataConsumer

Address of the `ChainLinkDataConsumer` contract.

```solidity
address public chainLinkDataConsumer
```

### rewardPool

Address of the `RewardPool` contract used for reward emission logic.

```solidity
address public rewardPool
```

### l1Sender

Address of the `L1SenderV2` contract responsible for bridging rewards.

```solidity
address public l1Sender
```

### aavePoolAddressesProvider

Address of the Aave `PoolAddressesProvider` used for yield generation.

```solidity
address public aavePoolAddressesProvider
```

### aavePoolDataProvider

Address of the Aave `PoolDataProvider`.

```solidity
address public aavePoolDataProvider
```

### aaveRewardsController

Address of the Aave `RewardControler`.

```solidity
address public aaveRewardsController;
```

### undistributedRewards

Accumulated rewards not yet distributed due to zero yield.

```solidity
uint256 public undistributedRewards
```

### minRewardsDistributePeriod

Minimum delay in seconds between reward distributions in a reward pool.

```solidity
uint256 public minRewardsDistributePeriod
```

## Write functions for the contract owner

### Distributor\_init

Initializes the `Distributor` contract with addresses of key protocol dependencies.

```solidity
function Distributor_init(
    address chainLinkDataConsumer_,
    address aavePoolAddressesProvider_,
    address aavePoolDataProvider_,
    address rewardPool_,
    address l1Sender_
) external initializer
```

| Name                         | Description                                                                       |
| ---------------------------- | --------------------------------------------------------------------------------- |
| `chainLinkDataConsumer_`     | Address of the `ChainLinkDataConsumer`  contract.                                 |
| `aavePoolAddressesProvider_` | Address of Aave `PoolAddressProvider` used for detecting the Aave `Pool` address. |
| `aavePoolDataProvider_`      | Aave protocol data provider address.                                              |
| `rewardPool_`                | Address of the `RewardPool` contract.                                             |
| `l1Sender_`                  | Address of the `L1SenderV2` for cross-chain messaging.                            |

### setChainLinkDataConsumer

Sets the `ChainLinkDataConsumer` contract address.

```solidity
function setChainLinkDataConsumer(address value_) public onlyOwner
```

| Name     | Description                              |
| -------- | ---------------------------------------- |
| `value_` | Address of the `ChainLinkDataConsumer` . |

### setL1Sender

Sets the `L1SenderV2` contract.

```solidity
function setL1Sender(address value_) public onlyOwner
```

| Name     | Description                           |
| -------- | ------------------------------------- |
| `value_` | Address of the `L1SenderV2` contract. |

### setAavePoolAddressesProvider

Sets the address of the Aave `PoolAddressProvider`.

```solidity
function setAavePoolAddressesProvider(address value_) public onlyOwner
```

| Name     | Description                 |
| -------- | --------------------------- |
| `value_` | Aave pool contract address. |

### setAavePoolDataProvider

Sets the `AaveProtocolDataProvider` contract address.

```solidity
function setAavePoolDataProvider(address value_) public onlyOwner
```

| Name     | Description                               |
| -------- | ----------------------------------------- |
| `value_` | Aave pool data provider contract address. |

### setAaveRewardsController

Sets the `AaveRewardsController` contract address.

```solidity
function setAaveRewardsController(address value_) public onlyOwner
```

### setRewardPool

Sets the address of the `RewardPool` contract.

```solidity
function setRewardPool(address value_) public onlyOwner
```

| Name     | Description                          |
| -------- | ------------------------------------ |
| `value_` | Address of the reward pool contract. |

### setMinRewardsDistributePeriod

Updates the minimum time delay between reward distributions in secodns.

```solidity
function setMinRewardsDistributePeriod(uint256 value_) public onlyOwner
```

| Name     | Description                                 |
| -------- | ------------------------------------------- |
| `value_` | Minimum reward distribution delay. Seconds. |

### setRewardPoolLastCalculatedTimestamp

Sets the last reward calculation timestamp for a reward pool.

```solidity
function setRewardPoolLastCalculatedTimestamp(
  uint256 rewardPoolIndex_, 
  uint128 value_
) public onlyOwner
```

| Name               | Description                                               |
| ------------------ | --------------------------------------------------------- |
| `rewardPoolIndex_` | Index of the reward pool.                                 |
| `value_`           | Timestamp to set as last calculated timestamp in seconds. |

### addDepositPool

Registers a new deposit pool associated with a specific reward pool. Only callable by the contract owner.

```solidity
function addDepositPool(
  uint256 rewardPoolIndex_,
  address depositPoolAddress_,
  address token_,
  string memory chainLinkPath_,
  Strategy strategy_
) external onlyOwner
```

| Name                  | Description                                                  |
| --------------------- | ------------------------------------------------------------ |
| `rewardPoolIndex_`    | Index of the reward pool to associate with the deposit pool. |
| `depositPoolAddress_` | Address of the deposit pool contract.                        |
| `token_`              | Address of the ERC20 token used in the deposit pool.         |
| `chainLinkPath_`      | Path for Chainlink price feed used to determine token price. |
| `strategy_`           | Strategy for yield generation (e.g., AAVE, NONE, NO\_YIELD). |

### updateDepositTokensPrices

Updates the price data for all tokens in deposit pools associated with the given reward pool.

```solidity
function updateDepositTokensPrices(uint256 rewardPoolIndex_) public
```

| Name               | Description                                                |
| ------------------ | ---------------------------------------------------------- |
| `rewardPoolIndex_` | Index of the reward pool whose token prices need updating. |

### withdrawUndistributedRewards

Transfers undistributed MOR rewards to the `L1SenderV2` for final distribution. Callable by owner.

```solidity
function withdrawUndistributedRewards(
  address user_, 
  address refundTo_
) external payable onlyOwner
```

| Name        | Description                                  |
| ----------- | -------------------------------------------- |
| `user_`     | Address of the recipient.                    |
| `refundTo_` | Address to refund gas in case of LZ failure. |

## Write functions

### distributeRewards

Distribute latest MOR rewards to the `DepositPools`.

```solidity
function distributeRewards(uint256 rewardPoolIndex_) public
```

| Name               | Description               |
| ------------------ | ------------------------- |
| `rewardPoolIndex_` | Index of the reward pool. |

### withdrawYield

Transfers accumulated yield to the `L1SenderV2` contract.

```solidity
function withdrawYield(
  uint256 rewardPoolIndex_,
  address depositPoolAddress_
) external
```

| Name                  | Description                                        |
| --------------------- | -------------------------------------------------- |
| `rewardPoolIndex_`    | Index of the reward pool.                          |
| `depositPoolAddress_` | Address of the deposit pool withdrawing the yield. |

### claimAaveRewards

Claims Morpheus rewards from Aave protocol for the specified deposit assets. Return claimed amount.

```solidity
function claimAaveRewards(
  address[] calldata assets_,
  uint256 amount_,
  address to_,
  address reward_
) external onlyOwner returns (uint256 claimedAmount_)
```

| Name      | Description                                                           |
| --------- | --------------------------------------------------------------------- |
| `assets_` | Array of aToken addresses to claim rewards for.                       |
| `amount_` | Amount of rewards to claim (use type(uint256).max for all available). |
| `to_`     | Address that will receive the rewards.                                |
| `reward_` | Address of the reward token.                                          |

## Write functions for the DepositPool contract&#x20;

### supply

Allows a `DepositPool` to supply tokens and participate in yield generation. Return deposited amount.

```solidity
function supply(
  uint256 rewardPoolIndex_,
  address holder_,
  uint256 amount_
) external returns (uint256)
```

| Name               | Description                          |
| ------------------ | ------------------------------------ |
| `rewardPoolIndex_` | Index of the associated reward pool. |
| `holder_`          | The token holder (staker) address.   |
| `amount_`          | Amount of tokens to supply. Wei.     |

### withdraw

Allows a `DepositPool` to withdraw tokens previously deposited. Return the withdrawn amount.

```solidity
function withdraw(
  uint256 rewardPoolIndex_, 
  address receiver_,
  uint256 amount_
) external returns (uint256)
```

| Name               | Description                          |
| ------------------ | ------------------------------------ |
| `rewardPoolIndex_` | Index of the associated reward pool. |
| `receiver_`        | The token receiver address.          |
| `amount_`          | Amount of tokens to withdraw. Wei.   |

### sendMintMessage

Sends a mint message to the `L1SenderV2` for reward minting.

```solidity
function sendMintMessage(
    uint256 rewardPoolIndex_,
    address user_,
    uint256 amount_,
    address refundTo_
) external payable
```

| Name               | Description                             |
| ------------------ | --------------------------------------- |
| `rewardPoolIndex_` | Index of the reward pool.               |
| `user_`            | Address of the user to mint tokens for. |
| `amount_`          | Amount of rewards to mint. Wei.         |
| `refundTo_`        | Refund address for LayerZero.           |

## Read functions

### getDistributedRewards

Returns the amount of rewards already distributed to a deposit pool.

```solidity
function getDistributedRewards(
    uint256 rewardPoolIndex_,
    address depositPoolAddress_
) external view returns (uint256)
```

| Name                  | Description                  |
| --------------------- | ---------------------------- |
| `rewardPoolIndex_`    | Index of the reward pool.    |
| `depositPoolAddress_` | Address of the deposit pool. |

### supportsInterface

Used for interface detection (ERC165). Returns true if the contract supports a specific `interfaceId_`. Supports `IDistributor`, `IERC165`.

```solidity
function supportsInterface(bytes4 interfaceId_) external pure returns (bool)
```

### version

Returns the current version of the contract.

```solidity
function version() external pure returns (uint256)
```


---

# Agent Instructions: 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:

```
GET https://gitbook.mor.org/smart-contracts/documentation/distribution-protocol/v7-protocol/contracts/distributor.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
