Impact
Medium
Likelihood
High
Description
The Vote() function is GaugeController.sol used for the gauge weights, However the calculation for the votingPower is based on veRAACToken.balanceOf(msg.sender) , A malicious user can first vote by Account-1, then transfer the veRAACToken to Account-2 and then vote again (This can happen again and again with use of Multiple accounts). This can cause the Gauge to have more votes then intended resulting in manipulated Voting.
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);
if (votingPower == 0) revert NoVotingPower();
uint256 oldWeight = userGaugeVotes[msg.sender][gauge];
userGaugeVotes[msg.sender][gauge] = weight;
_updateGaugeWeight(gauge, oldWeight, weight, votingPower);
emit WeightUpdated(gauge, oldWeight, weight);
}
This same can be done in BaseGauge.sol::voteDirection()
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();
totalVotes = processVote(
userVotes[msg.sender],
direction,
votingPower,
totalVotes
);
emit DirectionVoted(msg.sender, direction, votingPower);
}
Mitigation
Implementation of a system where there is no dependence on balance of tokens for voting.