Core Contracts

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

Critical: Potential Overflow Risk in poolBoost.totalBoost Accumulation

Summary

The poolBoost.totalBoost value in the updateUserBoost function is intended to accumulate over time as users' boosts are updated. This can lead to very large values, posing a significant risk of overflow Or underflow. Ensuring that the contract can handle large values safely is crucial for maintaining long-term stability and preventing potential exploits.

Vulnerability Details

The poolBoost.totalBoost value is updated based on the difference between the new and old boost values of users. Over time, this value can grow significantly, especially if the pool has many users or if individual boosts are substantial.

Current Code:

if (newBoost >= oldBoost) {
poolBoost.totalBoost = poolBoost.totalBoost + (newBoost - oldBoost); // <- HERE
} else {
poolBoost.totalBoost = poolBoost.totalBoost - (oldBoost - newBoost); // <- HERE
}

Issues:

  • Large Values: As more users join the pool and their boosts are updated, poolBoost.totalBoost can become very large.

  • Overflow/Underflow: Although Solidity 0.8.x includes built-in overflow checks, explicitly handling large values can prevent future issues.

Impact

While this issue does not introduce a security vulnerability, it impacts the long-term stability and scalability of the contract. Ensuring that poolBoost.totalBoost can handle large values is crucial for maintaining the contract's reliability.

Tools Used

  • Solidity Compiler

  • Manual Code Review

Recommendations

  1. Use Safe Math Operations:

    • Use a safe math library like OpenZeppelin’s SafeMath to ensure that arithmetic operations are performed safely.

    Updated Code:

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
using SafeMath for uint256;
if (newBoost >= oldBoost) {
poolBoost.totalBoost = poolBoost.totalBoost.add(newBoost.sub(oldBoost));
} else {
poolBoost.totalBoost = poolBoost.totalBoost.sub(oldBoost.sub(newBoost));
}
  1. Monitor and Log Values:

    • Implement monitoring and logging to track the values of poolBoost.totalBoost and ensure they remain within expected ranges.

  2. Consider Upper Limits:

    • Depending on the use case, consider setting upper limits on poolBoost.totalBoost to prevent it from becoming excessively large.

Primary Recommendation

  1. Set max_totalBoost:

    • Define a maximum allowed value for poolBoost.totalBoost to prevent it from growing excessively large.

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
error TotalBoostExceedsLimit();
uint256 public constant MAX_TOTAL_BOOST = 10**18; // Example value, adjust as needed
using SafeMath for uint256;
if (newBoost >= oldBoost) {
if (poolBoost.totalBoost.add(newBoost.sub(oldBoost)) > MAX_TOTAL_BOOST) {
revert TotalBoostExceedsLimit();
}
poolBoost.totalBoost = poolBoost.totalBoost.add(newBoost.sub(oldBoost));
} else {
poolBoost.totalBoost = poolBoost.totalBoost.sub(oldBoost.sub(newBoost));
}

OR

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
error TotalBoostExceedsLimit();
uint256 public constant MAX_TOTAL_BOOST = 10**18; // Example value, adjust as needed
using SafeMath for uint256;
function updateUserBoost(address user, address pool) external override nonReentrant whenNotPaused {
if (paused()) revert EmergencyPaused();
if (user == address(0)) revert InvalidUser();
if (pool == address(0)) revert InvalidPool();
if (!supportedPools[pool]) revert PoolNotSupported();
UserBoost storage userBoost = userBoosts[user][pool];
PoolBoost storage poolBoost = poolBoosts[pool];
uint256 oldBoost = userBoost.amount;
uint256 newBoost = _calculateBoost(user, pool, 10000); // Base amount
userBoost.amount = newBoost;
userBoost.lastUpdateTime = block.timestamp;
uint256 totalBoostAfterUpdate;
if (newBoost >= oldBoost) {
// Calculate the new total boost using SafeMath
totalBoostAfterUpdate = poolBoost.totalBoost.add(newBoost.sub(oldBoost));
// Check if the new total boost exceeds the maximum allowed value
if (totalBoostAfterUpdate > MAX_TOTAL_BOOST) {
revert TotalBoostExceedsLimit();
}
// Update the pool's total boost
poolBoost.totalBoost = totalBoostAfterUpdate;
} else {
// Update the pool's total boost using SafeMath
poolBoost.totalBoost = poolBoost.totalBoost.sub(oldBoost.sub(newBoost));
}
// Update the pool's working supply
poolBoost.workingSupply = newBoost;
poolBoost.lastUpdateTime = block.timestamp;
emit BoostUpdated(user, pool, newBoost);
emit PoolBoostUpdated(pool, poolBoost.totalBoost, poolBoost.workingSupply);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!