Core Contracts

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

Incorrect boost state update in lock() and increase()

Summary

The _boostState.totalVotingPower is set to a stale total supply value, which does not account for the new tokens being minted for the current lock.

Vulnerability Details

In the lock() and increase() functions, the _updateBoostState() function is invoked before the new veRAAC tokens are minted.

function lock(uint256 amount, uint256 duration) external nonReentrant whenNotPaused {
---SNIP---
_lockState.createLock(msg.sender, amount, duration);
// @audit-issue boost state updated prematurely
>> _updateBoostState(msg.sender, amount);
---SNIP---
// @audit-issue Minting done later
>> _mint(msg.sender, newPower);
emit LockCreated(msg.sender, amount, unlockTime);
}
function increase(uint256 amount) external nonReentrant whenNotPaused {
// Increase lock using LockManager
_lockState.increaseLock(msg.sender, amount);
// @audit-issue boost state updated prematurely
_updateBoostState(msg.sender, locks[msg.sender].amount);
---SNIP---
// @audit-issue Minting done later
_mint(msg.sender, newPower - balanceOf(msg.sender));
emit LockIncreased(msg.sender, amount);
}

This means that when _updateBoostState() accesses totalSupply(), it retrieves the total supply of veRAAC tokens before the new tokens from the current locking operation are added to the total supply.

function _updateBoostState(address user, uint256 newAmount) internal {
---SNIP---
>> _boostState.totalVotingPower = totalSupply();
---SNIP---
}

As a result, the value of _boostState.totalVotingPower is based on an outdated total supply, which does not reflect the new tokens that are about to be minted.


Impact

The contract state is left in an inconsistent state that do not accurately reflect the real status of things.
For example:
getBoostState() is used to retrieve the boost state as follows:

function getBoostState() external view returns (BoostStateView memory) {
return BoostStateView({
minBoost: _boostState.minBoost,
maxBoost: _boostState.maxBoost,
boostWindow: _boostState.boostWindow,
>> totalVotingPower: _boostState.totalVotingPower, // @audit-issue Inaccurate value returned
totalWeight: _boostState.totalWeight
});
}

The returned totalVotingPower is based on an outdated total supply, which is stale. This is is misleading and depending on the usecase, may result in erroneous outcome.

Tools Used

Manual Review

Recommendations

The _updateBoostState() function should be called after the minting of new tokens in both the lock() and increase() functions.

Updates

Lead Judging Commences

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

veRAACToken::_updateBoostState should be called later inside lock/increase

Support

FAQs

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

Give us feedback!