Core Contracts

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

Amount is added twice in the ``increase()`` function of veRAACToken.sol.

Summary

Amount is added twice in the increase() function of veRAACToken.sol thus doubling the power.

Vulnerability Details

In the increase() function:

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
);
// Update checkpoints
uint256 newPower = uint256(uint128(newBias));
_checkpointState.writeCheckpoint(msg.sender, newPower);
// Transfer additional tokens and mint veTokens
raacToken.safeTransferFrom(msg.sender, address(this), amount);
_mint(msg.sender, newPower - balanceOf(msg.sender));
emit LockIncreased(msg.sender, amount);
}

_lockState.increaseLock(msg.sender, amount); is called first in which:

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);
}

additionalAmount is added to lock.amount. and lock is stored in storage for Lock storage lock = state.locks[user];.

After that these lines are executed in the increase() function:

LockManager.Lock memory userLock = _lockState.locks[msg.sender];
(int128 newBias, int128 newSlope) = _votingState.calculateAndUpdatePower(
msg.sender,
userLock.amount + amount,
userLock.end
);

Here we can see that, amount is again added to userLock.amount in _votingState.calculateAndUpdatePower() to calcuate newBias which is used as power.

Thus, amount is added twice one in increaseLock() of LockManager and other in increase().

Impact

User gains twice the power while increasing the lock which shouldn't be the case. Voting power is very important for governance and proposal voting in this protocol which is implemented in Governance.sol and this issue may impact the protocol severely. Thus the high severity.

Also, voting power of a user is used in calcuating rewards in FeeCollector.sol, and in BoostController.sol for boost calculation.

Tools Used

Manual Analysis

Recommendations

Update voting power before increasing the lock or remove + amount in the _votingState.calculateAndUpdatePower() function while calculating newBias.

Updates

Lead Judging Commences

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

Give us feedback!