Core Contracts

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

Incorrect Working Supply Update in BoostController

Summary

The updateUserBoost function incorrectly sets poolBoost.workingSupply = newBoost, overwriting the total instead of accumulating user boosts. This corrupts the pool's working supply, leading to miscalculations in rewards.

Vulnerability Details

Current problematic implementation: /BoostController.sol#updateUserBoost

function updateUserBoost(address user, address pool) external override nonReentrant whenNotPaused {
UserBoost storage userBoost = userBoosts[user][pool];
PoolBoost storage poolBoost = poolBoosts[pool];
uint256 oldBoost = userBoost.amount;
uint256 newBoost = _calculateBoost(user, pool, 10000);
userBoost.amount = newBoost;
userBoost.lastUpdateTime = block.timestamp;
if (newBoost >= oldBoost) {
poolBoost.totalBoost = poolBoost.totalBoost + (newBoost - oldBoost);
} else {
poolBoost.totalBoost = poolBoost.totalBoost - (oldBoost - newBoost);
}
poolBoost.workingSupply = newBoost; // This line is incorrect

Impact

  • All reward calculations using workingSupply become inaccurate

  • Users receive incorrect boost multipliers

  • Reward distribution becomes unfairly skewed

Tools Used
Manual

Recommendations

Track workingSupply as the sum of all userBoost.amount in the pool, adjusting it by the difference between oldBoost and newBoost.

function updateUserBoost(address user, address pool) external override nonReentrant whenNotPaused {
UserBoost storage userBoost = userBoosts[user][pool];
PoolBoost storage poolBoost = poolBoosts[pool];
uint256 oldBoost = userBoost.amount;
uint256 newBoost = _calculateBoost(user, pool, userBoost.stakedAmount);
// Update user boost
userBoost.amount = newBoost;
userBoost.lastUpdateTime = block.timestamp;
// Track working supply as sum of all user boosts
poolBoost.workingSupply = poolBoost.workingSupply - oldBoost + newBoost;
// Update total boost
poolBoost.totalBoost = poolBoost.totalBoost + newBoost - oldBoost;
poolBoost.lastUpdateTime = block.timestamp;
emit BoostUpdated(user, pool, newBoost);
emit PoolBoostUpdated(pool, poolBoost.totalBoost, poolBoost.workingSupply);
}
Updates

Lead Judging Commences

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