Core Contracts

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

Boost state total voting power incorrectly stored

Summary

The boost state's total voting power is incorrectly stored due to updating it before minting/burning which means rewards boost calculations will always work with outdated and incorrect values.

Vulnerability Details

When users lock RAAC tokens for veRAAC tokens or increase their existing lock, an update to the global boost state is invoked. The _updateBoostState() function does as the name suggests and updates some important values:

function _updateBoostState(address user, uint256 newAmount) internal {
// Update boost calculator state
_boostState.votingPower = _votingState.calculatePowerAtTimestamp(user, block.timestamp);
_boostState.totalVotingPower = totalSupply();
_boostState.totalWeight = _lockState.totalLocked;
_boostState.updateBoostPeriod();
}

Namely the votingPower, totalVotingPower and totalWeight. Now if we go and take a look at lock(), we can see that the function is called before the minting of new veRAAC tokens is done:

function lock(uint256 amount, uint256 duration) external nonReentrant whenNotPaused {
...
// Create lock position
_lockState.createLock(msg.sender, amount, duration);
_updateBoostState(msg.sender, amount); // @audit boost state is first updated
...
// Mint veTokens
_mint(msg.sender, newPower); // @audit then new tokens are minted, boost state updates with outdated total supply
...
}

Which means that the boost state's totalVotingPower will always be updated with the wrong amount of outdated totalSupply(). This also happens in increase():

function increase(uint256 amount) external nonReentrant whenNotPaused {
// Increase lock using LockManager
_lockState.increaseLock(msg.sender, amount);
_updateBoostState(msg.sender, locks[msg.sender].amount);
...
_mint(msg.sender, newPower - balanceOf(msg.sender));
emit LockIncreased(msg.sender, amount);
}

Impact

The global boost state is an important parameter in relation to "Provides boost calculations for rewards". Due to this issue in lock() and increase(), the total voting power will always be outdated and incorrect which will render all rewards calculations based on the booststate incorrect.

Tools Used

Manual Review

Recommendations

Update the boost state at the end of the function flow after adjusting lock, checkpoint, votingstate and any minting/burning of tokens.

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!