The GaugeController.sol::vote() function uses veRAACToken.balanceOf() to determine a user's voting power instead of veRAACToken.getVotingPower(). This bypasses the core vote-escrow mechanism where voting power should be weighted by both the amount of tokens locked and the lock duration. Additionally, user whose locks have expired can continue to vote on key protocol decision despite having zero voting power.
In the GaugeController contract, the vote() function determines voting influence using:
However, this only retrieves the raw balance of locked tokens without considering the lock duration. The protocol implements a vote-escrow model similar to Curve's veCRV where voting power should be a function of both:
Amount of tokens locked
Duration of the lock (longer locks = more voting power)
The correct voting power should be obtained through veRAACToken.getVotingPower() which properly calculates the time-weighted voting power using the VotingPowerLib:
Additionally, users can keep voting once their locks have expired as the balance indicates they have voting power when they should have zero.
High:
Users receive voting weight solely based on their locked token amount, ignoring lock duration
This breaks the vote-escrow incentive mechanism where longer lock commitments should grant greater voting influence
Users who have zero voting power can keep impacting the protocol once their locks have expired
High - Happens on every vote, not preconditions required.
Replace veRAACToken.balanceOf(msg.sender) with veRAACToken.getVotingPower(msg.sender) in the vote() function:
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.