Distributor

v1 and v2

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>].

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.

mapping(address => bool) public isDepositTokenAdded;

distributedRewards

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

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

depositPoolAddresses

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

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

rewardPoolLastCalculatedTimestamp

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

mapping(uint256 => uint128) public rewardPoolLastCalculatedTimestamp;

isPrivateDepositPoolAdded

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

mapping(uint256 => bool) public isPrivateDepositPoolAdded

chainLinkDataConsumer

Address of the ChainLinkDataConsumer contract.

address public chainLinkDataConsumer

rewardPool

Address of the RewardPool contract used for reward emission logic.

address public rewardPool

l1Sender

Address of the L1SenderV2 contract responsible for bridging rewards.

address public l1Sender

aavePoolAddressesProvider

Address of the Aave PoolAddressesProvider used for yield generation.

address public aavePoolAddressesProvider

aavePoolDataProvider

Address of the Aave PoolDataProvider.

address public aavePoolDataProvider

aaveRewardsController

Address of the Aave RewardControler.

address public aaveRewardsController;

undistributedRewards

Accumulated rewards not yet distributed due to zero yield.

uint256 public undistributedRewards

minRewardsDistributePeriod

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

uint256 public minRewardsDistributePeriod

Write functions for the contract owner

Distributor_init

Initializes the Distributor contract with addresses of key protocol dependencies.

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.

function setChainLinkDataConsumer(address value_) public onlyOwner
Name
Description

value_

Address of the ChainLinkDataConsumer .

setL1Sender

Sets the L1SenderV2 contract.

function setL1Sender(address value_) public onlyOwner
Name
Description

value_

Address of the L1SenderV2 contract.

setAavePoolAddressesProvider

Sets the address of the Aave PoolAddressProvider.

function setAavePoolAddressesProvider(address value_) public onlyOwner
Name
Description

value_

Aave pool contract address.

setAavePoolDataProvider

Sets the AaveProtocolDataProvider contract address.

function setAavePoolDataProvider(address value_) public onlyOwner
Name
Description

value_

Aave pool data provider contract address.

setAaveRewardsController

Sets the AaveRewardsController contract address.

function setAaveRewardsController(address value_) public onlyOwner

setRewardPool

Sets the address of the RewardPool contract.

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.

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.

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.

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.

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.

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.

function distributeRewards(uint256 rewardPoolIndex_) public
Name
Description

rewardPoolIndex_

Index of the reward pool.

withdrawYield

Transfers accumulated yield to the L1SenderV2 contract.

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.

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

supply

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

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.

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.

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.

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.

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

version

Returns the current version of the contract.

function version() external pure returns (uint256)

Last updated

Was this helpful?