Function unstake
and unstakeVested
resets the unredeemedEpoch
, which causes the user to suffer reward loss.
https://github.com/Cyfrin/2024-08-fjord/blob/main/src/FjordStaking.sol#L449-L494
The unstake
function is used to withdraw the tokens staked by the user during the _epoch
period. However, in the contract, when all the tokens staked by the user during this period are withdrawn, the unredeemedEpoch
will be reset. This operation will cause the user to suffer reward losses.
Here is a specific example:
Bob stakes 1000 tokens when epoch=1.
Next, Bob stakes 1000 token when epoch=10. At the same time, he gets 1000 reward tokens. And we know his unredeemedEpoch
= 10. That is to say, if Bob performs an operation (such as staking or unstaking) when epoch is greater than 10, the tokens he staked at epoch=10 will be rewarded.
Bob unstake his all tokens with _epoch
=1. So the unredeemedEpoch
will be 0.
After a period of time, for example epoch
=20, Bob want to claimReward. However, his reward is still 1000 reward tokens(no growth) as unredeemedEpoch
= 0. The following logic does not work:
The same issue occurs in the function unstakeVested
.
Users lose their rewards.
Vscode
Don’t reset the unclaimedRewards
.
OR
Check if the _epoch
is equal to currentEpoch
.
Users that try to unstake tokens from an earlier epoch after they staked in the current epoch will have their ` unredeemedEpoch` set to 0, leading to them being unable to access the newly staked tokens. Impact: High – Tokens are lost Likelihood: Medium – It happens every time a user performs the respective sequence of calls. It’s not always but it’s also not a low likelihood scenario. It’s normal usage of the protocol, that doesn’t necessarily require special conditions.
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.