A vulnerability exists in the staking mechanism where users can lose their pending rewards if they stake additional shares without first claiming their rewards. This occurs because the system resets the user's lastValuePerShare
to the current valuePerShare
during staking, effectively discarding any unclaimed rewards earned since their last interaction.
The issue arises in the stake
function, specifically during the reward accumulation process:
When a user stakes, the system calculates their pending rewards using the formula:
After calculating the pending rewards, the system updates the user's lastValuePerShare
to the current valuePerShare
.
If the user does not claim their pending rewards before staking again, the rewards are lost, as the lastValuePerShare
is reset without transferring the earned rewards to the user.
The vulnerability is present in the following functions:
_updateLastValuePerShare
:
stake
:
accumulateActor(actorId)
return the reward of the user but this value is not used.
User A stakes 10 shares at valuePerShare = 0.1
.
Over time, valuePerShare
increases to 0.2.
User A stakes again without claiming rewards:
Pending rewards: (0.2 - 0.1) * 10 = 1 WETH
.
lastValuePerShare
is updated to 0.2.
The 1 WETH reward is lost because it was not claimed before staking.
user call stake -> wethRewardDistribution.accumulateActor(actorId);
-> _updateLastValuePerShare(self, actor, ud60x18(actor.shares));
-> valueChange = _getActorValueChange(self, actor);
Loss of User Funds: Users can lose their earned rewards if they stake additional shares without claiming rewards first.
User Frustration: Users may be unaware of the need to claim rewards before staking, leading to frustration and loss of trust in the protocol.
Financial Loss: Depending on the size of the rewards and the number of affected users, this vulnerability could result in significant financial losses.
Manual Code Review: The vulnerability was identified through a detailed review of the staking and reward distribution logic.
Scenario Testing: Simulated user interactions to understand the impact of staking without claiming rewards.
Modify the stake
function to automatically claim pending rewards before updating the user's shares or revert when user have pending rewards.
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.