MOR distribution. Step #2
The DepositPool
contract is responsible for the internal allocation of MOR tokens among participants who have staked tokens in the pool. While the total amount of MOR rewards is calculated and assigned per pool by the external Distributor
contract, the DepositPool
determines how those rewards are split among individual users.
Staking and virtual stake
When a user deposits tokens, they are immediately forwarded to the Distributor
contract for yield generation. However, within DepositPool
, the user’s deposit, applied multipliers (such as power factor bonuses or referral boosts), and resulting virtual stake are recorded. The virtual stake is calculated by multiplying the user’s actual deposit by their multipliers, thus capturing not just the amount staked but also the user’s commitment and contribution to the protocol.
Daily MOR allocation and cumulative reward coefficient
Unlike yield sources like Aave that accrue rewards continuously, stETH generates yield via a rebasing mechanism once per day. As a result, MOR distribution from the Distributor
to each DepositPool
also happens daily. This timing constraint ensures alignment with stETH’s yield schedule.
Internally, each DepositPool uses a cumulative reward coefficient to represent how many MOR tokens have been distributed per unit of virtual stake. When new MOR tokens are allocated to the pool, the coefficient is increased accordingly, reflecting the new available rewards.
Reward Calculation Formula
User rewards are calculated lazily — that is, only when a user interacts with the contract (e.g., stake, withdraw, or claim), rather than updating every user on each reward deposit. The calculation is performed using the following logic:
uint256 userReward = pendingRewards + virtualStake * (poolRewardCoefficient - userRewardCoefficient);
pendingRewards
- rewards that were calculated after the stake or withdrawal of depositToken — that is, after the user’s share was modified.virtualStake
- the user’s current stake after applying multipliers.poolRewardCoefficient
- the current accumulated MOR per unit of virtual stake across the entire pool.userRewardCoefficient
- the coefficient stored at the time of the user’s last interaction.
The poolRewardCoefficient
is updated globally when new rewards are distributed. It is calculated as:
uint256 poolRewardCoefficient += distributedRewards / totalVirtualStake;
distributedRewards
- is the amount of MOR tokens allocated to the pool during distribution.totalVirtualStake
- is the sum of all users’ virtual stake (after applying lock/referral multipliers) at the time of distribution.
This model allows each user’s reward to be efficiently and fairly computed based on the delta in the coefficient since their last update.
Claiming and Unstaking
When a user claims MOR tokens or unstakes from the pool, the contract first updates their reward using the above formula. Then, it issues the corresponding MOR amount and updates the user’s stored coefficient to the latest global value. This ensures that each user receives exactly their fair share of the distributed tokens.
Design Advantages
By utilizing a cumulative coefficient and lazy updates, the DepositPool
can support a large number of users without incurring high gas costs on reward distribution. While it doesn’t determine the total amount of MOR emitted, it guarantees an efficient and accurate internal distribution that reflects both user behavior and their contribution to the system.
Last updated
Was this helpful?