DeFiFoundry
20,000 USDC
View results
Submission Details
Severity: medium
Invalid

Incorrect Reward Distribution When Multiple Epochs Are Missed

Vulnerability Details:

The _checkEpochRollover function calculates pendingRewardsPerToken by summing all rewards that have accumulated since the last epoch that was processed. This amount is intended to be distributed for a single epoch, as all the pending rewards are accounted for in the rewardPerToken for a single epoch. However, if multiple epochs are missed, the same pendingRewardsPerToken value is applied across all missed epochs. This leads to an over-distribution of rewards.

Moreover, totalRewards is only incremented once with the pendingRewards value. As a result, in subsequent epochs, the available rewards for distribution are more than they should be. This will prevent users from claiming the rewards they are entitled to, as the contract’s reserved rewards for previous epochs are not accounted for.

function _checkEpochRollover() internal {
uint16 latestEpoch = getEpoch(block.timestamp);
if (latestEpoch > currentEpoch) {
//Time to rollover
currentEpoch = latestEpoch;
if (totalStaked > 0) {
uint256 currentBalance = fjordToken.balanceOf(address(this));
// now distribute the rewards to the users coming in the current epoch
uint256 pendingRewards = (currentBalance + totalVestedStaked + newVestedStaked)
- totalStaked - newStaked - totalRewards;
uint256 pendingRewardsPerToken = (pendingRewards * PRECISION_18) / totalStaked;
totalRewards += pendingRewards;
for (uint16 i = lastEpochRewarded + 1; i < currentEpoch; i++) {
rewardPerToken[i] = rewardPerToken[lastEpochRewarded] + pendingRewardsPerToken;
emit RewardPerTokenChanged(i, rewardPerToken[i]);
}
} else {
...
}
totalStaked += newStaked;
totalVestedStaked += newVestedStaked;
newStaked = 0;
newVestedStaked = 0;
lastEpochRewarded = currentEpoch - 1;
}
}

Impact:

  • The same pendingRewardsPerToken being applied to multiple epochs results in distributing more rewards than the contract holds.

  • Since totalRewards is only incremented once in the case where multiple epochs are missed, reserved rewards are not accounted for in future calculations, potentially leading to situations where users cannot claim their rewards.

Tools Used:

  • Manual analysis

Recommendation:

Modify the _checkEpochRollover function to correctly account for rewards when multiple epochs are missed. Ensure that the function recalculates and distributes rewards appropriately for each missed epoch, and accurately updates totalRewards to ensure that users can claim their rewards for previous epochs.

Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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