Core Contracts

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

Inflated Voting Power Calculation in veRAACToken `increase` Function Leads to Governance Manipulation.

Summary:

The increase function in the veRAAC token contract incorrectly calculates and updates a user's voting power, resulting in an inflated voting power balance. This is due to the user's locked RAAC balance being updated before the voting power calculation, which then incorrectly adds the increase amount again to the user's balance during the power calculation. This leads to an inflated voting power, allowing users maniplate and influence in governance proposals, receive unfair rewards.

Vulnerability Details:

The increase function updates the user's locked RAAC balance before recalculating their voting power. Specifically, the amount being increased is added to the user's existing balance within the increaseLock function itself. Subsequently, the calculateAndUpdatePower function uses this already updated balance to calculate the new voting power. However, the logic within the voting power calculation appears to add the increase amount again to the user's balance, effectively counting it twice. This results in an inflated voting power.

// In veRAACToken.sol
function increase(uint256 _amount) public {
// ... other code ...
lockState.increaseLock(msg.sender, amount); // Balance updated FIRST
_votingState.calculateAndUpdatePower(
msg.sender,
userLock.amount + amount, // <-- increase amount again added to user's new balance.
userLock.end
);
// ... other code ...
}

Impact:

Users receive an inflated voting power, which can have significant consequences:

  • Governance Manipulation: Users can potentially influence the governance proposals due to their artificially inflated voting power. Malicious actors could exploit this to manipulate proposals in their favor.

  • Unfair Rewards Distribution: If voting power is used to determine rewards, users with inflated voting power will receive a disproportionately larger share of rewards, unfairly penalizing other users.

  • Protocol Instability: The incorrect voting power can destabilize the protocol by allowing users to vote on proposals with more weight than they should have, potentially leading to unintended or harmful outcomes.

Proof of Concept:

  1. Mahi locks 100 RAAC tokens for365 days. This gives her, 25 voting power (veRAAC Tokens). Her locked balance is 100, and her voting power is 25.

  2. Mahi calls increase(100).

  3. Inside the increaseLock function, Mahi's locked balance is updated to 200 (100 + 100).

  4. calculateAndUpdatePower is called, which incorrectly adds the increase amount again calculateAndUpdatePower(200 + 100).

  5. The calculation uses 300 as the locked balance, leading to a voting power to be 75 veRAAC tokens.

  6. Mahi now has 75 voting power instead of the correct 50 (based on her 200 locked RAAC). She has effectively been granted voting power for tokens she hasn't locked for the required duration. This inflated voting power gives her undue influence in any governance proposals.

Proof Of Code:

  1. Use this guide to intergrate foundry into your project: foundry

  2. Create a new file FortisAudits.t.sol in the test directory.

  3. Add the following gist code to the file: Gist Code

  4. Run the test using forge test --mt test_FortisAudits_InflatedVotingPower -vvvv.

function test_FortisAudits_InflatedVotingPower() public {
address mahi = makeAddr("mahi");
uint256 amount = 100e18;
uint256 duration = 31536000 seconds ;
vm.startPrank(initialOwner);
raacToken.setMinter(initialOwner);
raacToken.mint(mahi , amount * 2);
vm.stopPrank();
vm.startPrank(mahi);
raacToken.approve(address(veraacToken), amount * 2);
console.log("Mahi Locks %d RAACToken for 365 days", amount);
veraacToken.lock(amount, duration);
console.log("Mahi gets %d of voting power", veraacToken.balanceOf(mahi));
veraacToken.increase(amount);
console.log("Mahi increase the lock amount by %d", amount);
vm.stopPrank();
uint256 correct_voting_power = (((amount * 2) * 365 days) / 1460 days);
console.log("Correct voting power of Mahi after increase lock %d", correct_voting_power);
console.log("Mahi gets %d of voting power, which is inflated voting power", veraacToken.balanceOf(mahi));
}
[PASS] test_Fortis_InflatedVotingPower() (gas: 715551)
Logs:
Mahi Locks 100000000000000000000 RAACToken for 365 days
Mahi gets 25000000000000000000 of voting power
Mahi increase the lock amount by 100000000000000000000
Correct voting power of Mahi after increase lock 50000000000000000000
Mahi gets 75000000000000000000 of voting power, which is inflated voting power

Tools Used:

  • Manual code review.

Recommended Mitigation:

To mitigate this vulnerability, the increase function should be modified to ensure the voting power is calculated correctly, and that the increased amount is not added new updated balance second time during the power calculation.

// In veRAACToken.sol
function increase(uint256 _amount) public {
// ... other code ...
lockState.increaseLock(msg.sender, amount); // Balance updated FIRST
_votingState.calculateAndUpdatePower(
msg.sender,
- userLock.amount + amount, // <-- increase amount again added to user's new balance.
+ userLock.amount, // <-- Remove the increase amount from the calculation
userLock.end
);
// ... other code ...
}
Updates

Lead Judging Commences

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

veRAACToken::increase doubles the voting power of users

Support

FAQs

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