Core Contracts

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

Incorrect Lock State Reference Leading to Broken Boost Calculations

Summary

The veRAACToken contract maintains duplicate lock tracking mechanisms but only updates one while referencing the empty one for boost calculations, leading to broken boost mechanics and incorrect reward distributions.

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/tokens/veRAACToken.sol#L254

Vulnerability Details

The contract has two parallel structures for tracking user locks:

  1. A public mapping that's never updated:
    mapping(address => Lock) public locks;

  2. The actually used lock state in LockManager:
    LockManager.LockState private _lockState;

The critical issue occurs in the increase function:

function increase(uint256 amount) external nonReentrant whenNotPaused {
_lockState.increaseLock(msg.sender, amount);
// INCORRECT: Uses empty mapping
_updateBoostState(msg.sender, locks[msg.sender].amount); // Always returns 0
// Should use:
// _updateBoostState(msg.sender, _lockState.locks[msg.sender].amount);

Impact

  • All boost values will be calculated as if users have 0 locked tokens

  • Affects reward distributions across the entire protocol

Recommendations

  1. Remove Redundant Mapping
    mapping(address => Lock) public locks;

  2. Fix Boost State Updates

function increase(uint256 amount) external nonReentrant whenNotPaused {
_lockState.increaseLock(msg.sender, amount);
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
_updateBoostState(msg.sender, userLock.amount);
}
  1. Add Lock State Validation

function _updateBoostState(address user, uint256 newAmount) internal {
LockManager.Lock memory userLock = _lockState.locks[user];
require(userLock.amount > 0, "No active lock found");
// ... rest of function
}
  1. Update Public View Functions

function getLockedBalance(address account) external view returns (uint256) {
return _lockState.locks[account].amount;
}
Updates

Lead Judging Commences

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

veRAACToken::increase uses locks[msg.sender] instead of _lockState.locks[msg.sender] inside _updateBoostState call

Support

FAQs

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