Core Contracts

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

userBoosts.amount in BoostController will have different scales when using different functions to update it

Summary

In the BoostController.sol there are 2 ways to update the userBoosts[user][pool].amount,
1. calling the delegateBoost function

2.Calling the updateUserBoost function

The bug is that both these functions update the value differently, with a scaling difference of 1e18 to 1e4

Vulnerability Details

function delegateBoost(
address to,
uint256 amount,
uint256 duration
) external override nonReentrant {
if (paused()) revert EmergencyPaused();
if (to == address(0)) revert InvalidPool();
if (amount == 0) revert InvalidBoostAmount();
if (duration < MIN_DELEGATION_DURATION || duration > MAX_DELEGATION_DURATION)
revert InvalidDelegationDuration();
uint256 userBalance = IERC20(address(veToken)).balanceOf(msg.sender);
if (userBalance < amount) revert InsufficientVeBalance();
UserBoost storage delegation = userBoosts[msg.sender][to];
if (delegation.amount > 0) revert BoostAlreadyDelegated();
delegation.amount = amount;
// amount can be a maximum of userBalance which is the balance of veRAACToken of user

In the delegateBoost function the userBoost.amount is updated as the amount, which can reach a maximum of the users veRAACToken balance (this is of the order 1e18 since the decimals of the token is 18).

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;
// calls the _calculateBoost function which returns value < 2.5e4

In the updateUserBoost function the variable is updated as the output of the calculateBoost function, but this function returns boost*1e4, (basically a value in between the boost range).
This can be easily verified by checking the last line of the
_calculateBoost function which limits the return value to the MAXBOOST_AMOUNT

uint256 maxBoostAmount = amount * MAX_BOOST / 10000;
if (boostedAmount > maxBoostAmount) {
return maxBoostAmount;
}
return boostedAmount;
}

Note: here the amount = 1e4 (this is the value supplied by the updateUserBoost function

Impact

User can inflate his userBoost.amount value

Tools Used

manual review

Recommendations

ensure both the updations are similar

Updates

Lead Judging Commences

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

BoostController contract manages delegations and boosts using the same structure for both delegations and calculated boosts

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

BoostController contract manages delegations and boosts using the same structure for both delegations and calculated boosts

Support

FAQs

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