The pendingRewardsPerToken value calculation in the FjordStaking._checkEpochRollover function does not account for the newStaked amount which has already being staked in the previous epoch. This breaks the rewards accounting in the FjordStaking contract.
The FjordStaking._checkEpochRollover function calculates the pendingRewardsPerToken value as shown below:
The above value is calculated after a new epoch rollover. Hence the newStaked amount belongs to the previous epoch (currentEpoch - 1). The newStaked value is considered while calculating the pendingRewards amount as shown below:
But this newStaked is not taken into account when dividing the pendingRewards amount by the totalStaked amount. The newStaked amount belongs to the earlier epoch since the epoch increased in the current execution of the FjordStaking._checkEpochRollover function. As a result the calculated pendingRewardsPerToken is bigger than the correct amount since division happened with a lesser denominator (totalStaked) as newStaked is not added to it.
As a result the reward calculations for the stakers is broken since the calculated rewardPerToken[epoch] for the subsequent epochs are erroneously calculated since they contain amounts more than the correct amounts (Since the denominator in the pendingRewardsPerToken calculation was less than the correct amount). Hence this breaks the rewards accounting system in the FjordStaking contract.
https://github.com/Cyfrin/2024-08-fjord/blob/main/src/FjordStaking.sol#L694-L709
Manual Review and VSCode
Hence it is recommended to add the newStaked amount to the totalStaked amount when the pendingRewardsPerToken value is being calculated. The modified line of code is shown below:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.