MOR distribution. Step #1

This document describes how MOR token rewards are distributed across deposit pools within the protocol.

Overview

The Distributor contract is responsible for periodically allocating MOR rewards to registered deposit pools under a specific reward pool. The distribution process ensures that each deposit pool receives a fair share of MOR tokens based on its generated yield and token value in USD.

Reward distribution flow

The distribution of MOR tokens is executed through the distributeRewards function and follows the steps below:

1. Fetch Emission Rewards from RewardPool

The Distributor contract queries the RewardPool contract to calculate the total amount of MOR tokens to emit for a given reward pool over the elapsed time period. This is based on a linear decay model defined per pool.

uint256 rewards = rewardPool.getPeriodRewards(
  rewardPoolIndex,
  lastCalculatedTimestamp,
  uint128(block.timestamp)
);

The contract updates the rewardPoolLastCalculatedTimestamp to the current block timestamp after fetching.

2. Update Token Prices for Each Deposit Pool

The Distributor updates USD prices for all deposit tokens in the reward pool using Chainlink data feeds:

bytes32 chainLinkPathId = chainLinkDataConsumer.getPathId(depositPool.chainLinkPath);
uint256 price = chainLinkDataConsumer.getChainLinkDataFeedLatestAnswer(chainLinkPathId);

This ensures that all token values are normalized to the same unit (USD) before comparison.

3. Calculate USD Yield Per Deposit Pool

For each deposit pool, the protocol calculates the USD-denominated yield:

uint256 yield = (tokenBalance - lastUnderlyingBalance).to18(decimals) * tokenPrice;
  • tokenBalance - current token or aToken balance held by the contract.

  • lastUnderlyingBalance - previously recorded balance (after last reward allocation).

  • to18() - utility to normalize token decimals to 18.

  • tokenPrice - latest USD price from Chainlink.

The lastUnderlyingBalance is updated after this step.

4. Compute Yield Shares and Assign Rewards

Once all yields are collected and expressed in USD, the contract calculates the relative share of each deposit pool:

uint256 rewardShare = (poolYield * totalRewards) / totalYield;
  • poolYield - USD yield of the deposit pool.

  • totalYield - sum of all deposit pool yields.

  • totalRewards - emission amount retrieved from RewardPool.

Rewards are then added to the distributedRewards mapping:

distributedRewards[rewardPoolIndex][depositPoolAddress] += rewardShare;

If totalYield is zero, rewards are temporarily stored in undistributedRewards.

Notes

  • For private pools (strategy NO_YIELD), all rewards go to the only pool registered under that reward index.

  • The reward assignment is proportional to real yield, meaning pools with higher dollar-denominated yield get more MOR.


Last updated

Was this helpful?