Closed code423n4 closed 1 year ago
dmvt marked the issue as duplicate of #156
RedVeil marked the issue as sponsor confirmed
dmvt changed the severity to QA (Quality Assurance)
Revert back to M as requested by @dmvt
dmvt marked the issue as satisfactory
dmvt marked the issue as not a duplicate
dmvt marked the issue as duplicate of #191
dmvt changed the severity to 3 (High Risk)
dmvt marked the issue as partial-50
dmvt marked the issue as satisfactory
Lines of code
https://github.com/code-423n4/2023-01-popcorn/blob/d95fc31449c260901811196d617366d6352258cd/src/utils/MultiRewardStaking.sol#L305-L314
Vulnerability details
Impact
In
MultiRewardStaking.changeRewardSpeed
the newrewardsEndTimetamp
is calculated based on the current balance of reward tokens in the contract. However, a fraction of this balance might already be accrued and accounted as reward, but just has not been claimed yet. This can cause more tokens to be claimable than the contract contains, leading to a "first come first serve" scenario for users concerning rewards.Proof of Concept
The function
MultiRewardStaking.changeRewardSpeed
uses the current reward token balance of the contract as input for the calculation of the newrewardsEndTimeStamp
:The idea is that the current balance of reward tokens is what still needs to be distributed (as the name
remainder
implies). However, as mentioned under #Impact a fraction of this balance might already be attributed to users and is just unclaimed. Using the full balance will lead torewardsEndTimeStamp
being later than it should be, causing more tokens to be accounted for claiming than the contract holds:Tools Used
Manual Review
Recommended Mitigation Steps
Only the fraction of reward tokens that has not yet accrued should be used to calculate the
rewardsEndTimestamp
when changing the rewardspeed. A separate variable might be necessary to track the amount of tokens that are eligible to be claimed. That variable would need to be incremented on all_accrueStatic
calls that occur whentotalSupply > 0
.