Core Contracts

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

veRAACToken Total Voting Power Calculation Issue

Summary

The getTotalVotingPower function incorrectly returns the total supply of veRAACToken instead of the actual decayed voting power. Since voting power decays over time but total supply does not, this discrepancy leads to an overestimation of total voting power, causing miscalculations in reward distribution within the FeeCollector contract.


Vulnerability Details

The getTotalVotingPower function should return the actual aggregate voting power based on decay calculations. Instead, it directly returns totalSupply(), which does not decay. This results in reward calculations being skewed, as the sum of individual voting powers will always be smaller than the assumed total voting power.

Code Reference:

/**
* @notice Gets the total voting power of all veRAAC tokens
* @dev Returns the total supply of veRAAC tokens
* @return The total voting power across all holders
*/
function getTotalVotingPower() external view override returns (uint256) {
return totalSupply();
}

Exploitation Scenario:

  1. A user locks tokens and receives veRAACToken with full voting power.

  2. Over time, the user's voting power decays as expected.

  3. The getTotalVotingPower function, however, still returns the non-decayed total supply.

  4. In the _calculatePendingRewards function of the FeeCollector contract, total voting power is overestimated, causing incorrect reward calculations.

  5. As a result, users with valid voting power may receive a lower share of rewards than they should.

Affected Function in FeeCollector Contract:

function _calculatePendingRewards(address user) internal view returns (uint256) {
uint256 userVotingPower = veRAACToken.getVotingPower(user);
if (userVotingPower == 0) return 0;
uint256 totalVotingPower = veRAACToken.getTotalVotingPower();
if (totalVotingPower == 0) return 0;
uint256 share = (totalDistributed * userVotingPower) / totalVotingPower;
return share > userRewards[user] ? share - userRewards[user] : 0;
}

Impact

  • Incorrect Reward Distribution: The sum of users' actual voting power is lower than the falsely inflated total voting power, leading to users receiving fewer rewards than they should.


Updates

Lead Judging Commences

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

veRAACToken::getTotalVotingPower returns non-decaying totalSupply while individual voting powers decay, causing impossible governance quorums and stuck rewards in FeeCollector

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

veRAACToken::getTotalVotingPower returns non-decaying totalSupply while individual voting powers decay, causing impossible governance quorums and stuck rewards in FeeCollector

Support

FAQs

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