Core Contracts

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

veRAACToken#increase() can be revert in some time.

Vulnerability Details

When user want to increase lock, it is assumed that total veTokens will always increase, so it always minting:

function increase(uint256 amount) external nonReentrant whenNotPaused {
// Increase lock using LockManager
_lockState.increaseLock(msg.sender, amount);
_updateBoostState(msg.sender, locks[msg.sender].amount);
// Update voting power
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
@> (int128 newBias, int128 newSlope) = _votingState.calculateAndUpdatePower(
msg.sender,
userLock.amount + amount,
userLock.end
);
// Update checkpoints
uint256 newPower = uint256(uint128(newBias));
_checkpointState.writeCheckpoint(msg.sender, newPower);
// Transfer additional tokens and mint veTokens
raacToken.safeTransferFrom(msg.sender, address(this), amount);
@> _mint(msg.sender, newPower - balanceOf(msg.sender));
emit LockIncreased(msg.sender, amount);
}

But the bias (power) is reduced when the time passed, because unlockTime is keeping the same when increase:

function calculateAndUpdatePower(
VotingPowerState storage state,
address user,
uint256 amount,
uint256 unlockTime
) internal returns (int128 bias, int128 slope) {
if (amount == 0 || unlockTime <= block.timestamp) revert InvalidPowerParameters();
uint256 MAX_LOCK_DURATION = 1460 days; // 4 years
// FIXME: Get me to uncomment me when able
// bias = RAACVoting.calculateBias(amount, unlockTime, block.timestamp);
// slope = RAACVoting.calculateSlope(amount);
// Calculate initial voting power that will decay linearly to 0 at unlock time
@> uint256 duration = unlockTime - block.timestamp;
@> uint256 initialPower = (amount * duration) / MAX_LOCK_DURATION; // Normalize by max duration
@> bias = int128(int256(initialPower));
slope = int128(int256(initialPower / duration)); // Power per second decay
uint256 oldPower = getCurrentPower(state, user, block.timestamp);
state.points[user] = RAACVoting.Point({
bias: bias,
slope: slope,
timestamp: block.timestamp
});
_updateSlopeChanges(state, unlockTime, 0, slope);
emit VotingPowerUpdated(user, oldPower, uint256(uint128(bias)));
return (bias, slope);
}

So the new power can be reduced even when they increase locking amount due to underflow of newPower - balanceOf(msg.sender) formula.

Impact

When the time passed, it is required for user to locking more token than they should to be able to increase locking amount

Recommendations

Compare new power and balance of user before deciding to mint/burn

Updates

Lead Judging Commences

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

veRAACToken::increase underflows on newPower - balanceOf(msg.sender)

Support

FAQs

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