sherlock-audit / 2024-06-velocimeter-judging

11 stars 7 forks source link

sonny2k - RewardsDistributorV2.tokensPerWeek might be zero in some extreme cases #571

Closed sherlock-admin2 closed 3 months ago

sherlock-admin2 commented 3 months ago

sonny2k

Medium

RewardsDistributorV2.tokensPerWeek might be zero in some extreme cases

Summary

RewardsDistributorV2.tokens_per_week is used to record the amount of token to distribute per week, if its value is zero, it means there is no token to be distributed. In current implementation, there will be an extreme case when the RewardsDistributorV2._checkpoint_token isn't called for more than 20 weeks, some weeks in the past will have empty RewardsDistributorV2.tokens_per_week.

Vulnerability Detail

In RewardsDistributorV2._checkpoint_token, the function will update last_token_time to block.timestamp first, and then loop 20 WEEK in for-loop

64     function _checkpoint_token() internal {
...
69        uint t = lastTokenTime;
70        uint since_last = block.timestamp - t;
71         last_token_time = block.timestamp; <<<--- lastTokenTime is updated to block.timestamp
72        uint this_week = t / WEEK * WEEK;
73        uint next_week = 0;
74 
75         for (uint256 i = 0; i < 20; i++) { <<<--- here 20 is used, it means that the function will loop 20 weeks at most
...

And next time when RewardsDistributorV2._checkpoint_token is called, the function record RewardsDistributorV2.tokens_per_week from the timestamp the function is called instead of the RewardsDistributorV2.tokens_per_week hasn't been recorded. So if the RewardsDistributorV2._checkpoint_token hasn't been called in more than 20 weeks, the RewardsDistributorV2.tokens_per_week will be like: RewardsDistributorV2.tokens_per_week[week_00] -> value_00 RewardsDistributorV2.tokens_per_week[week_01] -> value_01 RewardsDistributorV2.tokens_per_week[week_02] -> value_02 ... RewardsDistributorV2.tokens_per_week[week_19] -> value_19 RewardsDistributorV2.tokens_per_week[week_20] -> 0 RewardsDistributorV2.tokens_per_week[week_21] -> 0 RewardsDistributorV2.tokens_per_week[week_22] -> 0 ... RewardsDistributorV2.tokens_per_week[week_nn] -> value_nn <<<<--- next RewardsDistributorV2._checkpoint_token is called, the RewardsDistributorV2.tokens_per_week will be updated from here RewardsDistributorV2.tokens_per_week[week_nm] -> value_nm

Impact

Because RewardsDistributorV2.tokens_per_week is used to calculate the amount of token a user can claim, if its value is 0, it means there will be no token to be claimed.

Code Snippet

https://github.com/sherlock-audit/2024-06-velocimeter/blob/main/v4-contracts/contracts/RewardsDistributorV2.sol#L64-L95

Tool used

Manual Review

References

This report is inspired by the report from Immunefi Alchemix Boost #31385

nevillehuang commented 3 months ago

Duplicate of #377, invalid, especially when checkpointing is permisionless, 20 weeks not called is extremely unrealistic