Core Contracts

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

Stale Lock Data Usage in `veRAACToken::increase` Function Leading to Inaccurate Calculations

Summary

The increase function in the veRAACToken contract uses stale lock data from the locks mapping instead of the updated data stored in _lockState.locks. This occurs because the locks mapping is never synchronized with _lockState.locks, leading to incorrect calculations in functions like _updateBoostState. This issue results in inaccurate boost calculations.

Vulnerability Details

The increase function increases the locked RAAC tokens by calling _lockState.increaseLock, which updates _lockState.locks. However, the function then uses the stale locks[msg.sender].amount value in _updateBoostState, as the locks mapping is never updated. This inconsistency arises because the contract maintains two separate data structures (_lockState.locks and locks) without synchronizing them.

mapping(address => Lock) public locks; // ❌
LockManager.LockState private _lockState;
function increase(uint256 amount) external nonReentrant whenNotPaused {
// Increase lock using LockManager
_lockState.increaseLock(msg.sender, amount);
// @audit-issue: Using stale data from `locks` mapping
_updateBoostState(msg.sender, locks[msg.sender].amount); // ❌ Uses stale data
// Rest of the function...
}

Root Cause:

The root cause of the issue is the inconsistency between the _lockState.locks and locks mappings. Specifically:

  1. Duplicate State Variables: The contract maintains two separate data structures for storing lock information:

    • _lockState.locks: A LockManager.LockState struct that is actively updated when locks are created, increased, or extended.

    • locks: A mapping (mapping(address => Lock)) that is never updated after initialization.

  2. Stale Data in locks Mapping: The locks mapping is not synchronized with _lockState.locks. As a result, any function that relies on locks[msg.sender].amount (e.g., _updateBoostState) uses stale or outdated data, while _lockState.locks contains the correct, updated lock information.

  3. Misuse of locks Mapping: The locks mapping is redundant and unnecessary since _lockState.locks already stores the same information. However, the contract inconsistently uses both, leading to incorrect calculations.

Impact

The _updateBoostState function uses stale data, leading to incorrect boost calculations for rewards, voting power calculations may be based on outdated lock amounts, affecting governance decisions.

Tools Used

Manual Review

Recommendations

  1. Use Updated Lock Data: Ensure the increase function uses the updated lock amount from _lockState.locks[msg.sender].amount in _updateBoostState.

function increase(uint256 amount) external nonReentrant whenNotPaused {
// Increase lock using LockManager
_lockState.increaseLock(msg.sender, amount);
// Use updated lock data from _lockState.locks
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
_updateBoostState(msg.sender, userLock.amount); // ✅ Uses updated data
// Rest of the function...
}
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.