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.
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.
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 theRewardsDistributorV2._checkpoint_token
isn't called for more than 20 weeks, some weeks in the past will have emptyRewardsDistributorV2.tokens_per_week
.Vulnerability Detail
In RewardsDistributorV2._checkpoint_token, the function will update
last_token_time
toblock.timestamp
first, and then loop 20 WEEK in for-loopAnd next time when
RewardsDistributorV2._checkpoint_token
is called, the function recordRewardsDistributorV2.tokens_per_week
from the timestamp the function is called instead of theRewardsDistributorV2.tokens_per_week
hasn't been recorded. So if theRewardsDistributorV2._checkpoint_token
hasn't been called in more than 20 weeks, theRewardsDistributorV2.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, theRewardsDistributorV2.tokens_per_week
will be updated from here RewardsDistributorV2.tokens_per_week[week_nm] -> value_nmImpact
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