Core Contracts

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

The voteDirection function in the BaseGauge.sol incorrectly fetches the voting Power of the user

Summary

The voteDirection function is ued for users to allow them to vote on direction. However when it fetches the votingPower it does it wrong.

Vulnerability Details

When a user calls voteDirecton function he needs enough voting power in order to vote. But the user can exploit and misuse this function. That is because the way the function tracks the voting power of the user is via balanceOF(msg.sender)'s veTokens and this is wrong because this will never return until the user calls withdraw function in the veRACToken.sol. As the voting power of an user is supposed to be reduced and eventially will come to 0 with time and when it does the user should not allowed to vote. 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
But due to the wrong tracking of votingPower here the user can simply decide not to call withdraw function in the veRAACToken.sol and now even if his votingPower has been reduced to 0 due to the linear reduction variant. This user will still be able to call on voteDirection irrespective of that.

Impact

A user can misuse this and vote on the direction even when his voting power has gone to 0

Tools Used

Manual Review

Recommendations

Insetad of using balanceOf use this instead to get the real voting power of the user:
+ uint256 votingPower = veRAACToken.getVotingPower(msg.sender); and remove this one
-uint256 votingPower = IERC20(IGaugeController(controller).veRAACToken()) .balanceOf(msg.sender);

Code Snippets

function voteDirection(uint256 direction) public whenNotPaused updateReward(msg.sender) {
if (direction > 10000) revert InvalidWeight();
uint256 votingPower = IERC20(IGaugeController(controller).veRAACToken()).balanceOf(msg.sender);
if (votingPower == 0) revert NoVotingPower(); //<- AUDIT this uses the balanceOf to track voting power which can be misleading and a malicious user might misuse this.
totalVotes = processVote(
userVotes[msg.sender],
direction,
votingPower,
totalVotes
);
emit DirectionVoted(msg.sender, direction, votingPower);
}```
Updates

Lead Judging Commences

inallhonesty Lead Judge 3 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.