Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: low
Invalid

Inefficient Reward Distribution Mechanism

Summary

https://github.com/Cyfrin/2024-09-stakelink/blob/main/contracts/core/rewardsPools/RewardsPool.sol

The distributeRewards function distributes newly deposited rewards to users based on their stake in the rewards pool. However, the function calculates the total rewards available for distribution using the following logic:

uint256 toDistribute = token.balanceOf(address(this)) - totalRewards;

While this may appear functional, it leads to inefficiencies in the reward distribution mechanism when rewards are deposited into the contract.

Code Reference

/**
* @notice distributes new rewards that have been deposited
**/
function distributeRewards() public virtual {
uint256 toDistribute = token.balanceOf(address(this)) - totalRewards;
totalRewards += toDistribute;
_updateRewardPerToken(toDistribute);
emit DistributeRewards(msg.sender, controller.totalStaked(), toDistribute);
}

Impact

This inefficiency can result in:

  1. Overestimation of Distributable Rewards: If the contract receives multiple deposits in a single transaction or at different times, the calculation could yield incorrect values, causing either excess rewards to be distributed (if prior rewards are not accounted correctly) or less than expected to be distributed.

  2. Gas Inefficiency: Users may end up paying more gas fees than necessary, especially if there are multiple deposits made in a short time frame.

  3. Poor User Experience: Users may experience confusion if their rewards appear to be inconsistent due to miscalculations in the distribution

Tools Used

Manual Review

Recommendations

Improve Reward Calculation Logic: Implement a more robust calculation that handles multiple deposits more efficiently. For instance, maintain a separate accounting for each deposit that clearly delineates between already accounted rewards and new rewards:

uint256 currentBalance = token.balanceOf(address(this));
uint256 toDistribute = currentBalance - totalRewards;
require(toDistribute > 0, "No new rewards to distribute");
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Out of scope

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.