Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: medium
Valid

The `GaugeController's` `vote` function tracks the votingPower of the user incorrectly.

Summary

The GaugeController's vote function tracks the votingPower of the user incorrectly which will result in returning voting power > than the user has

Vulnerability Details

The vote in the GaugeController is for the core voting functionality for gauge weights, what it does is that updates the gauge's weights based on the voting power of the user However the way it tracks or fetches the voting power of the user is incorrect as is uses the balanceOf of the user's veRAACTokens which he was minted at the time of locking his raacTokens. But the issue here is that the votingPower decreases linearly by time and after a particular time passes, the votingPower will go down to 0 and that is tracked in the veRAACToken and the fact that here the fetching of voting power is done through the balanceOf function is wrong and that is because this balanceOf() will always return the amount of tokens that user locked or minted at the time of locking his raacTokens. This is not the votingPower as the votingPower of the user is computed with a different function in the veRAACToken i.e getVotingPower And due to the computation of voting power being done by the balanceOf function the user can also call the vote even when his voting power has deceases and gone to 0 because of the lock expiry or end of duration. That is because the balanceOf will only return 0 when the user will call the withdraw function as this function is supposed to burn the tokens that the user got minted at the time of locking. The user might decide to never call the withdraw function and doing this he will freely be able to vote even though his voting power is 0. And if balOf will be used in the vote function this is what will be returned instead of the real votingPower that the user actually have

Impact

High impact as the user will be able to vote on gauge weights irrespective of the fact that if the voting is 0 or not .

Tools Used

Manual Review

Recommendations

Add this line to the function and remove this:

+ uint256 votingPower = veRAACToken.getVotingPower(msg.sender);

- uint256 votingPower = veRAACToken.balanceOf(msg.sender);

Code Snippets

function vote(address gauge, uint256 weight) external override whenNotPaused {
if (!isGauge(gauge)) revert GaugeNotFound();
if (weight > WEIGHT_PRECISION) revert InvalidWeight();
-> uint256 votingPower = veRAACToken.balanceOf(msg.sender); //AUDIT- This tracks the votingPower using `balanceOf which might return incorrect
//power as the balanceOf will never zero until the user calls withdraw function. Instead the getVotingPower(account) should be used here
//as that will return the true voting power considering the linearly decay thing too. so even if the user's voting power decays to 0
//after the duration end, he might no choose to withdraw and end up bypassing this check
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

BaseGauge::_applyBoost, GaugeController::vote, BoostController::calculateBoost use balanceOf() instead of getVotingPower() for vote-escrow tokens, negating time-decay mechanism

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.