31385 - [SC - Low] RewardsDistributortokensPerWeek might be zero i...

Submitted on May 17th 2024 at 22:21:00 UTC by @jasonxiale for Boost | Alchemix

Report ID: #31385

Report type: Smart Contract

Report severity: Low

Target: https://github.com/alchemix-finance/alchemix-v2-dao/blob/main/src/RewardsDistributor.sol

Impacts:

  • Protocol insolvency

Description

Brief/Intro

RewardsDistributor.tokensPerWeek is used to record the amount of alcx to distribute per week, if its value is zero, it means there is no alcx will be distributed. In current implementation, there will be an extreme case that if the RewardsDistributor.checkpointToken isn't called for more than 20 weeks, some weeks in the past will has empty RewardsDistributor.tokensPerWeek

Vulnerability Details

In RewardsDistributor._checkpointToken, the function will update lastTokenTime to block.timestamp first, and then loop 20 WEEK in for-loop

227     function _checkpointToken() internal {
...
232         uint256 t = lastTokenTime;
233         uint256 sinceLast = block.timestamp - t;
234         lastTokenTime = block.timestamp; <<<--- lastTokenTime is update to block.timestamp
235         uint256 thisWeek = (t / WEEK) * WEEK;
236         uint256 nextWeek = 0;
237 
238         for (uint256 i = 0; i < 20; i++) { <<<--- here 20 is used, it means that the function will loop 20 weeks at most
...
252         }
254     }

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

Impact Details

Because RewardsDistributor.tokensPerWeek is used to calcuate the amount of alcx a user can claim, if its value is 0, it means there will be no alcx can be claim.

References

Add any relevant links to documentation or code

Proof of Concept

Put the following code in src/test/Minter.t.sol, and run

As we can see from the above output, after two voter.distribute(); calls, there still some rd.tokensPerWeek contains 0

Last updated

Was this helpful?