Core Contracts

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

Incorrect Lock Amount Calculation in `veRAACToken::increase` Function Due to Redundant Addition

Summary

The increase function in the veRAACToken contract contains an issue where the lock amount is incorrectly calculated during voting power updates. Specifically, the function adds the amount parameter twice: once in _lockState.increaseLock and again in the voting power calculation. This redundancy leads to incorrect voting power calculations, potentially allowing users to gain more voting power than intended.

Vulnerability Details

The issue arises in the increase function, where the lock amount is updated in _lockState.increaseLock and then incorrectly used in the voting power calculation.

  1. _lockState.increaseLock:

    • This function increases the lock amount by additionalAmount and updates the lock.amount and state.totalLocked values.

    • After this call, lock.amount already includes the additionalAmount.

function increase(uint256 amount) external nonReentrant whenNotPaused {
// Increase lock using LockManager
@>> _lockState.increaseLock(msg.sender, amount);
_updateBoostState(msg.sender, locks[msg.sender].amount);
//...
function increaseLock(
LockState storage state,
address user,
uint256 additionalAmount
) internal {
Lock storage lock = state.locks[user];
if (!lock.exists) revert LockNotFound();
if (lock.end <= block.timestamp) revert LockExpired();
// Maximum lock amount
if (lock.amount + additionalAmount > state.maxLockAmount) revert AmountExceedsLimit();
// Maximum total locked amount
// if (state.totalLocked + additionalAmount > state.maxTotalLocked) revert AmountExceedsLimit();
@>> lock.amount += additionalAmount;
state.totalLocked += additionalAmount;
emit LockIncreased(user, additionalAmount);
}
  1. Voting Power Calculation:

    • The function retrieves the updated lock amount from _lockState.locks[msg.sender] but incorrectly adds the amount parameter again in the voting power calculation:

      (int128 newBias, int128 newSlope) = _votingState.calculateAndUpdatePower(
      msg.sender,
      userLock.amount + amount, // ❌ Redundant addition
      userLock.end
      );
    • This results in the lock amount being counted twice, leading to incorrect voting power calculations.

function increase(uint256 amount) external nonReentrant whenNotPaused {
// Increase lock using LockManager
_lockState.increaseLock(msg.sender, amount); // ✅ Increases lock.amount by `amount`
_updateBoostState(msg.sender, locks[msg.sender].amount);
// Update voting power
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
(int128 newBias, int128 newSlope) = _votingState.calculateAndUpdatePower(
msg.sender,
userLock.amount + amount, // ❌ Redundant addition
userLock.end
);
}

Root Cause:

  • The lock.amount is already updated in _lockState.increaseLock to include the amount parameter.

  • The voting power calculation incorrectly adds the amount parameter again, leading to double-counting.

Impact

Users may gain more voting power than intended, undermining the fairness of governance decisions.

Tools Used

Manual Review

Recommendations

The veRAACToken::increase function should use the updated lock.amount directly without adding the amount parameter again. Here's the corrected code:

function increase(uint256 amount) external nonReentrant whenNotPaused {
// Increase lock using LockManager
_lockState.increaseLock(msg.sender, amount); // ✅ Increases lock.amount by `amount`
_updateBoostState(msg.sender, locks[msg.sender].amount);
// Update voting power
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
(int128 newBias, int128 newSlope) = _votingState.calculateAndUpdatePower(
msg.sender,
userLock.amount, // ✅ Use updated lock.amount directly
userLock.end
);
// Rest of the function...
}
Updates

Lead Judging Commences

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