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

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.

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

aavePool

Address of the Aave Pool used for yield generation.

address public aavePool

aavePoolDataProvider

Address of the Aave Pool Data Provider.

address public aavePoolDataProvider

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 aavePool_,
    address aavePoolDataProvider_,
    address rewardPool_,
    address l1Sender_
) external initializer
Name
Description

chainLinkDataConsumer_

Address of the ChainLinkDataConsumer contract.

aavePool_

Address of Aave Pool used for yield strategies.

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.

setAavePool

Sets the address of the Aave Pool.

function setAavePool(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.

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.

Write functions for the DepositPool contract

supply

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

function supply(
  uint256 rewardPoolIndex_,
  uint256 amount_
) external
Name
Description

rewardPoolIndex_

Index of the associated reward pool.

amount_

Amount of tokens to supply. Wei.

withdraw

Allows a DepositPool to withdraw tokens previously deposited.

function withdraw(
  uint256 rewardPoolIndex_, 
  uint256 amount_
) external returns (uint256)
Name
Description

rewardPoolIndex_

Index of the associated reward pool.

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?