The RAAC protocol has created a GaugeController to control gauge weights and reward distribution for RWA and RAAC emissions. Users who have veRAACTokens can vote on specific gauges (RWA and RAAC). However, with the current logic in the _updateGaugeWeight(), gauge weights get distorted when votes come in, eventually leading to a DoS of the action, and what is worse to invalid reward calculations, as they depend on the gauge weights.
Gauges have specific weights assigned to them, which range from 1 to 10000 (i.e. percentage-based). Whenever users vote, the gauge weight is updated, based on the users voting power.
The issue comes from how the gauge weight is updated:
Gauge weights and user-related weights are in BIPS (i.e. 0-10000), however, the votingPower is the veRAACToken balance, and the veRAACToken has 18 decimals, which distorts the gauge weight value (making it > BIPS), and eventually leading to an overflow.
Example:
There is a RWA Gauge with a weight of 8000.
Alice has 100e18 veRAACTokens and votes for this gauge for 6000
In _updateGaugeWeight() -> newGaugeWeight = 8000 - 0 + (6000 * 100e18 / 10000) = 8000 + 60e18 ~ 60e18. The gauge weight is already invalid.
Alice decides to lock some more RAACTokens and now has 200e18 veRAACTokens, and decides to vote again, this time to set the vote to `8000.
In _updateGaugeWeight() -> newGaugeWeight = 60e18 - (6000 * 200e18 / 10000) + (8000 * 200e18 / 10000). This will revert as 60e18 - 120e18 will revert with an underflow, even before reachin the + (8000 * 200e18 / 10000).
Even if the revert case is not reached, the invalid gauge weights are then used to calculate the corresponding rewards and gauge distributions:
Gauge voting produces incorrect gauge weights and leads to DoS.
Manual review.
Fix is not trivial, as votingPower needs to be re-scaled to not be with e18 notation.
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.