Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: high
Valid

User will lose staking rewards if they stake again without claiming initial rewards

Summary

Users can stake their index tokens to earn a proportion of fees through the stake function in VaultRouterBranch. The amount of shares staked is set in the Distribution logic when setActorShares is called. It also keeps track of the current value per share at the time of staking. An issue occurs when a user attempts to stake again and this variable is updated without the user ever claiming their fees between the last and latest update.

Vulnerability Details

A user stakes and their shares are set in setActorShares where it also updates the last value share through _updateLastValuePerShare. This is where the current value is set to lastValuePerShare for future calculations.

function _updateLastValuePerShare(
Data storage self,
Actor storage actor,
UD60x18 newActorShares
)
private
returns (SD59x18 valueChange)
{
valueChange = _getActorValueChange(self, actor);
actor.lastValuePerShare = newActorShares.eq(UD60x18_ZERO) ? int256(0) : self.valuePerShare;
}

This way if the value per share were to increase, the staker would be eligible for the difference. This delta value calculation is done through _getActorValueChange. A problem arises if a user stakes a second time without claiming their current rewards. lastValuePerShare will be updated again and when the delta calculation is made the next time a user were to claim fees, they would only receive the difference from the second time they staked.

function _getActorValueChange(
Data storage self,
Actor storage actor
)
private
view
returns (SD59x18 valueChange)
{
SD59x18 deltaValuePerShare = sd59x18(self.valuePerShare).sub(sd59x18(actor.lastValuePerShare));
valueChange = deltaValuePerShare.mul(ud60x18(actor.shares).intoSD59x18());
}

The accumulate rewards function doesnt actually accumulate the rewards for the user up to this point. They would need to call claimFees to get rewards up to this point.

Impact

User can lose fees

Tools Used

Manual Review

Recommendations

Add logic for the user to claim before staking again or require the user to claim like in unstake

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Inside VaultRouterBranch if you stake wait some time then stake again makes you lose the rewards.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.