Core Contracts

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

Incorrect Boost Calculation Due to Outdated TotalSupply in veRAACToken::lock

Description

The veRAACToken contract updates boost state before minting new tokens in the veRAACToken::lock function. The veRAACToken::_updateBoostState function uses totalSupply for boost calculations, but this value hasn't been updated yet by the subsequent _mint call, leading to incorrect boost ratios.

function lock(uint256 amount, uint256 duration) external {
_lockState.createLock(msg.sender, amount, duration);
@> _updateBoostState(msg.sender, amount); // Uses outdated totalSupply
(int128 bias, int128 slope) = _votingState.calculateAndUpdatePower(...);
uint256 newPower = uint256(uint128(bias));
_checkpointState.writeCheckpoint(msg.sender, newPower);
@> _mint(msg.sender, newPower); // Updates totalSupply after boost calculation
}
function _updateBoostState(address user, uint256 newAmount) internal {
@> _boostState.totalVotingPower = totalSupply(); // Gets outdated value
_boostState.totalWeight = _lockState.totalLocked;
_boostState.updateBoostPeriod();
}

Example:

Initial state:
totalSupply = 1000 veRAACToken
User locks 500 RAAC
Current calculation:
boost = votingPower / totalVotingPower
= 500 / 1000 // Uses outdated totalSupply
= 0.5 // Incorrect ratio
Correct calculation (should be):
boost = votingPower / totalVotingPower
= 500 / 1500 // Should use updated totalSupply
= 0.33 // Correct ratio

Risk

Likelihood: High

  • Occurs on every lock operation

  • Affects all users creating new locks

  • No condition to prevent this miscalculation

Impact: Medium

  • Boosts are calculated with incorrect ratios

  • Users receive higher boost values than intended

  • Protocol's reward distribution becomes unbalanced

Recommended Mitigation

This ensures boost calculations use the correct, updated totalSupply value, leading to accurate boost ratios.

function lock(uint256 amount, uint256 duration) external nonReentrant whenNotPaused {
// ... initial checks ...
_lockState.createLock(msg.sender, amount, duration);
- _updateBoostState(msg.sender, amount);
(int128 bias, int128 slope) = _votingState.calculateAndUpdatePower(...);
uint256 newPower = uint256(uint128(bias));
_checkpointState.writeCheckpoint(msg.sender, newPower);
_mint(msg.sender, newPower);
+ _updateBoostState(msg.sender, amount); // Use updated totalSupply
emit LockCreated(msg.sender, amount, unlockTime);
}
Updates

Lead Judging Commences

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