Core Contracts

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

Double counting of lock amount in voting power calculation leads to inflated governance power

Description

In veRAACToken::increase, the voting power calculation adds the amount parameter to the existing userLock.amount after the lock has already been increased through LockManager::increaseLock. This results in double-counting the additional amount when calculating voting power, as the lock's amount is updated before the voting power calculation.

Proof of Concept

  1. User creates initial lock with 1000 tokens

  2. User calls veRAACToken::increase with 500 additional tokens

  3. LockManager::increaseLock updates lock.amount to 1500

  4. _votingState.calculateAndUpdatePower uses (1500 + 500) = 2000 for calculation

  5. Voting power is calculated based on 2000 tokens instead of correct 1500

Relevant code snippet:

// Lock amount is already increased at this point
_lockState.increaseLock(msg.sender, amount);
// Uses old amount + new amount (double counts increase)
(int128 newBias, int128 newSlope) =
_votingState.calculateAndUpdatePower(msg.sender, userLock.amount + amount, userLock.end);

Proof of Concept Test

Add to veRAACToken.test.js:

it("demonstrates double-counting in voting power when increasing lock", async () => {
const initialAmount = ethers.parseEther("1000");
const additional = ethers.parseEther("500");
const duration = 365 * 24 * 3600;
// Create initial lock
await veRAACToken.connect(users[0]).lock(initialAmount, duration);
const initialPower = await veRAACToken.balanceOf(users[0].address);
// Increase lock amount
await veRAACToken.connect(users[0]).increase(additional);
const postIncreasePower = await veRAACToken.balanceOf(users[0].address);
// Calculate expected 50% increase (1000 -> 1500)
const expectedIncrease = (initialPower * 15n) / 10n; // 1.5x
// Actual will show 2.0x increase due to double-counting
expect(postIncreasePower).to.be.gt(expectedIncrease);
});

Impact

High Severity - Creates artificially inflated voting power that:

  • Distorts governance voting outcomes

  • Allows users to gain disproportionate influence

  • Violates core tokenomics assumptions

Recommendation

  • Correct Approach: Use updated lock amount directly

+ Lock memory updatedLock = _lockState.getLock(msg.sender);
(int128 newBias, int128 newSlope) =
- _votingState.calculateAndUpdatePower(msg.sender, userLock.amount + amount, userLock.end);
+ _votingState.calculateAndUpdatePower(msg.sender, updatedLock.amount, updatedLock.end);
Updates

Lead Judging Commences

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