Core Contracts

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

Lock extension harms users

Summary

Extending a lock will sometimes cause only harm to the user by burning their veToken balance which is used for various calculations

Details

Assume a user locked 100 raac for 4 years (max lock) and was minted 100 veRaac.
2 years go by and user decides to call extend for a year extra
The following execution takes place in calculateAndUpdatePower

uint256 duration = unlockTime - block.timestamp; // 2 years left + 1 = 3 years
uint256 initialPower = (amount * duration) / MAX_LOCK_DURATION; // 100 x 3 / 4 = 75
bias = int128(int256(initialPower)); // 75
slope = int128(int256(initialPower / duration));
uint256 oldPower = getCurrentPower(state, user, block.timestamp);
state.points[user] = RAACVoting.Point({
bias: bias,
slope: slope,
timestamp: block.timestamp
});

User's new power is returned to extend, equal to 75. The following logic executes

uint256 oldPower = balanceOf(msg.sender); // 100
uint256 newPower = uint256(uint128(newBias)); // 75
_checkpointState.writeCheckpoint(msg.sender, newPower);
if (newPower > oldPower) {
_mint(msg.sender, newPower - oldPower);
} else if (newPower < oldPower) { // passes and burns 25 veRaac
_burn(msg.sender, oldPower - newPower);
}

Since old power is greater than new one, veRaac burn takes place.
User locked their funds for an extra year and lost 25 veRaac in the process. This is problematic since live ve.balanceOf(user) is used when performing boost calculations

function _calculateBoost(
address user,
address pool,
uint256 amount
) internal view returns (uint256) {
if (amount == 0) revert InvalidBoostAmount();
if (!supportedPools[pool]) revert PoolNotSupported();
// Get current weights without modifying state
(uint256 totalWeight, uint256 totalVotingPower, uint256 votingPower) = updateTotalWeight();
@> uint256 userBalance = IERC20(address(veToken)).balanceOf(user);
@> uint256 totalSupply = IERC20(address(veToken)).totalSupply();
}

User achieved nothing but lose out on boost rewards and lock away their funds for extra time. Even if user extends their lock for 2 extra years, no extra power can be added since newPower = oldPower and they will end up locking their funds for 2 years extra for nothing in return.

Current implementation causes only harm to users and discourages them from extending their locks.

Impact

Logic error, loss of rewards

Mitigation

There is no trivial fix for this, complete re-design is necessary

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!