Core Contracts

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

Incorrect logic in veRAACToken increase function

Vulnerability Details

function increase(uint256 amount) external nonReentrant whenNotPaused {
// Increase lock using LockManager
_lockState.increaseLock(msg.sender, 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,
userLock.end
);
....
}

We can see that lockState.increaseLock(msg.sender, amount);is being called in _increasewhich updates the _ _lockState of msg.sender

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; // lock.amount has been updated
state.totalLocked += additionalAmount;
emit LockIncreased(user, additionalAmount);
}

We can see that lock.amounthas been updated with 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);
// Update voting power
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
(int128 newBias, int128 newSlope) = _votingState.calculateAndUpdatePower(
msg.sender,
userLock.amount + amount,
userLock.end
);

However, when calling _votingState.calculateAndUpdatePower, the second argument adds the new amount to userLock.amount even though the userLock.amount has already been updated with amount. This creates a situation where the old userLock amount has been updated twice with the increase amountinstead of once.

Impact

An inflated amount is being passed to _votingState.calculateAndUpdatePower

Tools Used

Manual

Recommendations

Use userLock.amount without adding amount

(int128 newBias, int128 newSlope) = _votingState.calculateAndUpdatePower(
msg.sender,
userLock.amount
userLock.end
);
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.