The Fjord Staking contract does not allocate rewards to users who unstake before rewards are added, resulting in those users not receiving their entitled rewards for valid staking periods.
In the Fjord Staking contract, users stake FJORD tokens to earn rewards, which are distributed proportionally based on the amount staked. Rewards are allocated when the admin adds them to the contract:
All stakers should receive a proportional share of the rewards added by the admin. However, the issue is that when users stake during valid epochs and then unstake before the admin adds the rewards. The contract lacks a mechanism to allocate rewards for those stakers, even though they are entitled to a share for the valid epochs they participated in. The problem occurs because, upon unstaking, the totalStaked value of the user is reduced:
And when rewards are subsequently added, they are calculated based on the user's totalStaked (that was already reduced by the unstake operation):
As a result, the contract does not account for rewards owed to users who staked during valid epochs but unstaked before rewards were distributed.
Consider the following test case:
Alice stakes 1 ether during epoch 1.
After 6 weeks, the admin adds rewards for each epoch.
Alice claims her rewards for the past 6 weeks, successfully receiving 6 ether.
An additional 4 weeks pass without the admin adding rewards. During this time, Alice continues staking.
Alice unstakes her tokens, having not received rewards for epochs 7 to 11.
When the admin eventually adds rewards, Alice is unable to claim her share corresponding to epochs 7 to 11.
Copy and paste the following test case into test/unit/stake.t.sol:
Users who stake during valid epochs and then unstake before rewards are added do not receive their entitled rewards for the epochs in which they participated. This results in an unfair distribution of rewards and breaks a core invariant that stakers should be rewarded for epochs they stake in.
Manual Review
Consider implementing a mechanism to track and allocate rewards for users who unstake before rewards are added. This would ensure that all users receive the rewards they are entitled to for their staking period.
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.