The BaseGauge contract's reward calculation allows any futures staker to be rewarded with rewardPerTokenStored that have been accumulated since creation of contract. That means a user who hasn't been staking from the beginning will be rewarded the same as a user who has been staking since the beginning. Or in other words the contract assumes that every user staked when the rewardPerTokenStored is 0.
rewardPerToken Accumulation: The rewardPerToken value increases over time as rewards are distributed and staking occurs. This value persists even if no new rewards are being distributed.
Instant Benefit for New Stakers: When a new user stakes tokens, their rewardPerTokenPaid is always set after calculating the earned rewards. Thus new stakers instantly benefit from this accumulated rewardPerToken, even if no new rewards have been distributed since the previous user staked.
Not Accounting Already Accumulated rewardPerTokenStored: The rewardPerTokenStored should be updated before calculating the rewards for new stakers. This would ensure that new stakers only receive rewards based on the rewardPerTokenStored value at the time of staking, rather than benefiting from previously accumulated rewards.
Unfair Reward Distribution: Future stakers receives rewards based on the already accumulated rewardPerToken, while earlier stakers are penalized for their early participation. This creates an unfair and inequitable reward system.
Insufficient rewards for early stakers: Early stakers receive fewer rewards than they should, as the rewards are distributed based on the accumulated rewardPerTokenStored value, rather than the value at the time of staking. This causes a loss of rewards for early participants, also no incentive for early staking.
Scenario:
Alice stakes 100 tokens in the BaseGauge contract when rewardPerTokenStored is 0. She earns some rewards over time.
Bluedragon waits until rewardPerTokenStored has increased to 1000 before staking 100 tokens.
Bluedragon's rewardPerTokenPaid is set to 0 when they stake, and they instantly benefit from the accumulated rewards based on the rewardPerTokenStored value of 1000.
Alice, who has been staking since the beginning, receives rewards based on the rewardPerTokenStored value of 1000, but she has been staking since the rewardPerTokenStored was 0.
Bluedragon gains more rewards than Alice instantly, even though Alice has been staking longer.
Use this guide to intergrate foundry into your project: foundry
Create a new file FortisAudits.t.sol in the test directory.
Add the following gist code to the file: Gist Code
Run the test using forge test --mt test_FortisAudits_FutureStakersEarnsMoreThanEarlyStakers -vvvv.
Manual code review
To address this vulnerability, the rewardPerTokenPaid value should be updated to the current rewardPerTokenStored value when a user stakes tokens. This ensures that new stakers only receive rewards based on the current rewardPerTokenStored value, rather than benefiting from previously accumulated 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.