When a user votes second time on GaugeController, corresponding gauge's weight is calculated incorrectly.
Let's take a look at GaugeController.votefunction:
User's weight is recorded in userGaugeVotesand gauge's total weight is updated in _updateGaugeWeightfunction:
The function tries to update gauge's weight based on user's current vote (newWeight) and user's voting power.
The problem is that, the same votingPoweris used for old weight subtraction and new weight addition.
So if oldWeight > 0(i.e. user has pervious vote), gauge's weight will be moved by votingPower * (newWeight - oldWeight)
If a user has gained some serious more voting power between pervious vote and current vote, they can inflict more changes to gauge's weight than deserved.
A malicious user can exploit this vulnerability and then control gauge's weight at their whim. For example, let's assume attacker wants to set gauge's weight to 0. They can first create an initial voting position with full weight (10000) and dust voting power (1 wei). And then they can increase their voting power to half of total voting power and vote again with zero weight. In this scenario, gauge's weight will be set to dust amount.
Users with big voting power cannot vote again due to underflow in oldGaugeWeight - (oldWeight * votingPower / WEIGHT_PRECISION)
POC
First, integrate foundry into current project, and then create a file test/poc.t.sol with the following content and run forge test poc.t.sol -vvv
Console Output
Manual Review, Foundry
When updating gauge's weight, oldWeightshould be multiplied by user's voting power at the previous vote.
In order to do this, GaugeControllershould manage another state variable to store user's voting power at vote time.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.