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

Inconsistent Reward Calculation Due to Incorrect Handling of `newStaked` and `newVestedStaked` in `stakeVested` Function

Summary

In the stakeVested function, both newStaked and newVestedStaked are incremented by the staked amount _amount. This is problematic because the reward calculation logic in _checkEpochRollover uses these values to determine pendingRewardsPerToken, which may lead to incorrect reward distributions if newStaked is incremented erroneously.

Vulnerability Details

The stakeVested function incorrectly increments both newStaked and newVestedStaked:

newStaked += _amount; // Incorrectly increments newStaked
newVestedStaked += _amount; // Correctly increments newVestedStaked

Since the function is designed for staking vested NFTs (which are associated with FJORD tokens), only newVestedStaked should be incremented. The incorrect increment of newStaked can lead to the following issues:

  • Duplicate Reward Calculation: newStaked and newVestedStaked are used in _checkEpochRollover to calculate pendingRewardsPerToken and rewardPerToken. If newStaked is incremented unnecessarily, the rewards calculation will erroneously include the amount twice.

  • Potential Miscalculation: The reward calculation might distribute rewards based on inflated totalStaked values if newStaked is not handled correctly.

Relevant Code in _checkEpochRollover:

if (totalStaked > 0) {
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 {
for (uint16 i = lastEpochRewarded + 1; i < currentEpoch; i++) {
rewardPerToken[i] = rewardPerToken[lastEpochRewarded];
emit RewardPerTokenChanged(i, rewardPerToken[i]);
}
}

Impact

Incorrectly incrementing newStaked may lead to:

  • Incorrect Reward Distribution: Users might receive incorrect amounts of rewards due to the inflation of totalStaked in the calculation.

  • Systemic Reward Errors: Over time, the rewards distributed could be significantly skewed, affecting all users relying on accurate reward calculations.

Tools Used

Manual Code Review

Recommendations

Ensure that newStaked is only incremented in scenarios where new tokens are being staked directly (not in cases where vested NFTs are involved). Modify the stakeVested function to only increment newVestedStaked, reflecting the nature of the staked asset. additionally, consider also modifying the function _unstakeVested to:

  • Remove Adjustments to newStaked: Since newStaked is intended for direct token staking, it should not be decremented when handling vested NFTs.

Updates

Lead Judging Commences

inallhonesty Lead Judge
10 months ago
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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