Core Contracts

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

Incorrect Boost Calculation

Summary

The boost calculation in the contract is flawed because it uses the user's veRAAC balance (voting power) instead of their locked RAAC balance to determine the boost multiplier. This leads to incorrect reward calculations, potentially giving users unfair advantages or disadvantages.

Vulnerability Details

Root Cause

The boost calculation relies on the user's veRAAC balance (balanceOf(user)) instead of their locked RAAC balance (_lockState.locks[user].amount). This discrepancy occurs in the calculateBoost function:

function calculateBoost(address user, uint256 amount) external view returns (uint256 boostBasisPoints, uint256 boostedAmount) {
return _boostState.calculateTimeWeightedBoost(
balanceOf(user), // Uses veRAAC balance instead of locked RAAC balance
totalSupply(),
amount
);
}

Scenario

  • User A locks 1000 RAAC tokens for 4 years, receiving a high voting power (veRAAC balance).

  • User B locks 500 RAAC tokens for 1 year, receiving a lower voting power.

  • The boost calculation uses the veRAAC balance, giving User A a disproportionately high boost compared to User B, even though User B has a significant locked balance.

Steps to Reproduce

  • Deploy the veRAACToken contract with the RAAC token address.

  • User A locks 1000 RAAC tokens for 4 years (MAX_LOCK_DURATION).

  • User B locks 500 RAAC tokens for 1 year.

  • Call calculateBoost for User A and User B.

  • Observe that User A receives a disproportionately high boost compared to User B, even though User B has a significant locked balance.

  • Verify that the boost calculation is based on the veRAAC balance (balanceOf(user)) instead of the locked RAAC balance (_lockState.locks[user].amount).

Expected Behavior

The boost calculation should use the locked RAAC balance to ensure fair and accurate rewards.


Actual Behavior

The boost calculation uses the veRAAC balance, leading to incorrect and unfair rewards.

Code Example

// Simulate incorrect boost calculation
function testIncorrectBoostCalculation() public {
// Step 1: Deploy the contract
veRAACToken veRAAC = new veRAACToken(raacTokenAddress);
// Step 2: Simulate user locks
uint256 lockAmountA = 1000e18;
uint256 lockDurationA = 1460 days; // 4 years
veRAAC.lock(lockAmountA, lockDurationA);
uint256 lockAmountB = 500e18;
uint256 lockDurationB = 365 days; // 1 year
veRAAC.lock(lockAmountB, lockDurationB);
// Step 3: Calculate boosts
(uint256 boostA, ) = veRAAC.calculateBoost(userA, lockAmountA);
(uint256 boostB, ) = veRAAC.calculateBoost(userB, lockAmountB);
// Step 4: Verify that the boost calculation is incorrect
assert(boostA > boostB, "User A should have a higher boost due to higher veRAAC balance");
assert(boostB < boostA, "User B should have a lower boost due to lower veRAAC balance");
}

Output

  • User A receives a higher boost than User B, even though User B has a significant locked balance.

  • The boost calculation is based on the veRAAC balance (balanceOf(user)) instead of the locked RAAC balance (_lockState.locks[user].amount).

Impact

  • Users may receive incorrect rewards due to inaccurate boost calculations.

  • Users with high voting power but low locked balances could receive disproportionately high boosts.

  • Incorrect boosts could undermine user trust in the fairness of the reward distribution system.

Tools Used

Recommendations

  • Modify the calculateBoost function to use the locked RAAC balance (_lockState.locks[user].amount) instead of the veRAAC balance (balanceOf(user)).

function calculateBoost(address user, uint256 amount) external view returns (uint256 boostBasisPoints, uint256 boostedAmount) {
return _boostState.calculateTimeWeightedBoost(
_lockState.locks[user].amount, // Correct: Uses locked RAAC balance
totalSupply(),
amount
);
}
  • Ensure that the boost value is clamped to the valid range (MIN_BOOST to MAX_BOOST).

boostBasisPoints = Math.min(Math.max(boostBasisPoints, MIN_BOOST), MAX_BOOST);
  • Emit an event when the boost is calculated to improve transparency and facilitate debugging.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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

Give us feedback!