Core Contracts

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

workingSupply overwritten Instead of updated, leading to incorrect boost calculations

Summary

In BoostController.sol function updateUserBoost causes the workingSupply variable to be overwritten instead of being incremented or decremented properly. It seems to be an intended behaviour, however this results in the total working supply of the pool being artificially lowered, leading to incorrect boost calculations.

Vulnerability Details

The function updateUserBoost is responsible for updating a user's boost within a pool.

function updateUserBoost(address user, address pool) external override nonReentrant whenNotPaused {
if (paused()) revert EmergencyPaused();
if (user == address(0)) revert InvalidPool();
if (!supportedPools[pool]) revert PoolNotSupported();
UserBoost storage userBoost = userBoosts[user][pool];
PoolBoost storage poolBoost = poolBoosts[pool];
uint256 oldBoost = userBoost.amount;
// Calculate new boost based on current veToken balance
uint256 newBoost = _calculateBoost(user, pool, 10000); // Base amount
userBoost.amount = newBoost;
userBoost.lastUpdateTime = block.timestamp;
// Update pool totals safely
if (newBoost >= oldBoost) {
poolBoost.totalBoost = poolBoost.totalBoost + (newBoost - oldBoost);
} else {
poolBoost.totalBoost = poolBoost.totalBoost - (oldBoost - newBoost);
}
poolBoost.workingSupply = newBoost; // Set working supply directly to new boost
poolBoost.lastUpdateTime = block.timestamp;
emit BoostUpdated(user, pool, newBoost);
emit PoolBoostUpdated(pool, poolBoost.totalBoost, poolBoost.workingSupply);
}

This line overwrites the global workingSupply variable instead of properly accumulating or reducing the user's change in boost. This means:

  1. Each time a user updates their boost, the entire pool's workingSupply is replaced with just that user's new boost value.

  2. Existing contributions from other users are effectively lost, leading to an incorrectly low workingSupply value.

  3. When removeBoostDelegation is called, the workingSupply is decremented without considering whose boost is being reduced.

    For example:
    3.1. Alice updates his boost.

    3.2. Bob decide to delegate boost to Alex.

    3.3. When the duration of delegated boost expires Alex calls removeBoostDelegation and the working supply set from Alice gets decreased (This issue will be reported separately)

PoC

  1. Alice updates her boost to 500workingSupply = 500

  2. Bob updates his boost to 700workingSupply = 700 (Alice's 500 is lost!)

  3. Charlie updates his boost to 300workingSupply = 300 (Bob’s 700 is lost!)

This error causes the system to only consider the most recently updated user's boost, rather than the total sum of all active users' boosts.

Impact

The workingSupply will always be lower than expected, leading to incorrect boost calculations for all users in the pool.

  • Users who do not frequently update their boost may not be counted at all, unfairly reducing their participation in the system.

  • Boost-dependent mechanics (such as rewards and voting power) may be misallocated or exploited due to incorrect pool boost calculations.

  • Malicious actors could strategically manipulate boost updates.

Tools Used

Manual review

Recommendations

Instead of overwriting workingSupply, the contract should increment or decrement the difference between the new and old boost values:

if (newBoost >= oldBoost) {
poolBoost.workingSupply += (newBoost - oldBoost);
} else {
poolBoost.workingSupply -= (oldBoost - newBoost);
}

This ensures that the working supply accurately reflects all active users rather than just the most recent update.
It correctly adds new boost contributions and removes outdated ones, maintaining fairness and accuracy.
Prevents unexpected reductions in pool boost, preserving the integrity of the boost calculation system.

  1. This ensures that the working supply accurately reflects all active users rather than just the most recent update.

  2. It correctly adds new boost contributions and removes outdated ones, maintaining fairness and accuracy.

  3. Prevents unexpected reductions in pool boost, preserving the integrity of the boost calculation system.

Updates

Lead Judging Commences

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

BoostController::updateUserBoost overwrites workingSupply with single user's boost value instead of accumulating, breaking reward multipliers and allowing last updater to capture all benefits

Support

FAQs

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

Give us feedback!