31409 - [SC - Critical] Users can grief Bribe rewards forcing them to b...
Submitted on May 18th 2024 at 15:43:37 UTC by @OxAlix2 for Boost | Alchemix
Report ID: #31409
Report type: Smart Contract
Report severity: Critical
Target: https://github.com/alchemix-finance/alchemix-v2-dao/blob/main/src/Bribe.sol
Impacts:
Permanent freezing of unclaimed yield
Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
Description
Brief/Intro
When users vote in the Voter
contract, it calls Bribe::deposit
to "save" this vote, so that later when rewards come in for that Bribe can be distributed to users who voted. The opposite happens when users reset/withdraw their votes. However, there's 1 anomaly between the Bribe's deposit and withdrawal, where on deposit, Bribe is "checkpointing" the votes using:
And the opposite is not happening on the withdrawal, this allows users to mess up all the Bribe's rewards.
Vulnerability Details
When users vote in the Voter
contract, it calls Bribe::deposit
which increases the total votes of that Bribe, however, on withdrawal these votes aren't being subtracted. On the other hand, the Voter
contract allows users to continuously call the poke
function that resets and then vote again in the same gauges/bribes, without any condition on that function. This allows voters to continuously call the poke
function to skyrocket the total votes checkpoints in the Bribe, remember when poke
resets/withdraws the votes they are not being removed.
These total votes' checkpoints are being used in Bribe::earned
, to calculate the earned amount to each voter, it is being divided by, https://github.com/alchemix-finance/alchemix-v2-dao/blob/main/src/Bribe.sol#L261, which wrongly decrease the rewards for each user.
Impact Details
Griefing of users, as their rewards will be a lot less than what they "deserve", if there were even some rewards left.
The remaining unclaimed rewards will remain stuck forever in the contract.
References
https://github.com/alchemix-finance/alchemix-v2-dao/blob/main/src/Bribe.sol#L319-L329
Mitigation
Add the following in Bribe::withdraw
:
Proof of concept
Fork block number used: 19877251
Last updated