Closed c4-bot-9 closed 6 months ago
Picodes marked the issue as primary issue
othernet-global (sponsor) disputed
Canceling the unstake does not impact the amount of rewards that a user can claim as adding shares only entitles the user to rewards that are added after the shares have been added.
Picodes marked the issue as unsatisfactory: Insufficient proof
This report shows how by calling cancelUnstake
a user could increase its shares back to their previous level. It opens the doors to users front-running rewards distributions to increase their shares back but it seems to be a desirable behaviour
Lines of code
https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/staking/Staking.sol#L84-L97
Vulnerability details
Proof Of Concept
In Staking.sol, users can call
unstake()
to withdraw their xSALT. Whenunstake()
is called,_decreaseUserShare()
is called in StakingRewards.sol and the user receives some saltOnce
_decreaseUserShare()
executes, the user waits for the unstake duration to recover their salt.In the Staking contract, there is another function to cancel their unstaked position via
cancelUnstake()
This function will increase the user share based on what has been unstaked previously through_increaseUserShare()
._increaseUserShare()
refills thetotalRewards
for the pool as well as thevirtualRewards
of the user.Users with a staked position can call
unstake()
andcancelUnstake()
repeatedly to drain the contract of the rewards.Impact
Users can drain the rewards of the Staking contract.
Tools Used
Recommended Mitigation Steps
Recommend applying a penalty if the user decides to call
cancelUnstake()
. Otherwise, users can take advantage of the cancellation to get more rewards.Also, if there is a proposal that cannot reach quorum, a whale can simply call
unstake()
and wait for the proposal to pass before callingcancelUnstake()
to continue staking his funds.Assessed type
Context