Users lock RAAC tokens in exchange for veRAAC voting power, which decays linearly over time until reaching zero at the end of the lock period. However, the votes allocated to gauges do not decay—they remain valid even after a user's lock has expired. This allows expired voters to retain influence over reward distribution.
In a voting-escrow system, voting power follows a linear decay model, defined as:
Where:
Bias: The initial voting power at the time of locking.
Slope: The rate at which voting power decreases per second.
Users call vote to allocate their veRAAC voting power to different gauges, determining how rewards are distributed. The specified weight
of votingPower
is added to the total gauge weight:
gauges[gauge].weight = newGaugeWeight;
Note: There are other issues in the code snippets reported in separate submissions. These issues will be mentioned throughout this report to aid the reader in understanding how the system should behave.
The first extra issue is that the balanceOf
method doesn't return the decaying voting power. Instead, a method that computes the dynamic voting power (based on bias and slope) should be used.
The distributeRewards
function uses _calculateReward to calculate the reward amount for a gauge. The reward is a percentage determined by the gauge's weight and the total weight allocated to all gauges.
gaugeRewards = totalRewards * gaugeWeight / totalWeight
.
Note: typeWeights
and _calculateRWAEmission
/ _calculateRAACEmission
have same purpose and one of them should be removed.
The issue with this reward distribution system is that the gauge's weight doesn't decrease in accordance with the voter's actual votingPower
.
Imagine the following scenario:
Alice locks 1000 RAAC tokens for 4 years, receiving 1000 veRAAC voting power.
Alice votes to allocate 1000 voting power to gaugeA.
After 4 years, Alice’s veRAAC decays to 0, but her gauge votes remain active.
Bob locks 1000 RAAC tokens for 4 years, receiving 1000 veRAAC voting power.
Bob votes for gaugeB, but Alice’s expired votes are still counted, giving her unfair influence while she can freely unlock her RAAC tokens.
This results in stale votes influencing the system, making it unfair for active users.
Decayed votes retain voting power, allowing them to influence gauge rewards distribution indefinitely.
Unfair reward allocation distorts the intended function of the gauge system.
The GaugeController contract should implement a decaying gauge weight mechanism similar to the veRAACToken decay model.
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.