Core Contracts

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

Inconsistent Lock Data Storage in veRAACToken Leading to Incorrect Locked Balance and End Time Retrieval

Summary:

The LockManager library stores lock data inconsistently, updating the lock information in the LockState struct's mapping but not in the locks mapping of the veRAACToken contract. This inconsistency leads to the getLockedBalance and getLockEndTime functions in veRAACToken retrieving data from the wrong storage location, always returning zero values.

Vulnerability Details:

The LockManager library uses a LockState struct to manage lock information. This struct contains a mapping locks that stores Lock structs for each user. The createLock, increaseLock, and extendLock functions in LockManager correctly update this internal locks mapping within the LockState.

However, the veRAACToken contract also maintains its own locks mapping: mapping(address => Lock) public locks;. This mapping is not updated by the LockManager functions. The veRAACToken contract's getLockedBalance and getLockEndTime functions retrieve data from this veRAACToken.locks mapping, which remains at its default zero values because it's never written to.

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

// In LockManager.sol
struct LockState {
mapping(address => Lock) locks; // <--- Correctly updated here
// ... other fields
}
// In veRAACToken.sol
mapping(address => Lock) public locks; // <--- NOT updated by LockManager
// ...
function getLockedBalance(address account) external view returns (uint256) {
return locks[account].amount; // <--- Reads from the incorrect mapping
}
function getLockEndTime(address account) external view returns (uint256) {
return locks[account].end; // <--- Reads from the incorrect mapping
}

The lock, increase, and extend functions in veRAACToken call the corresponding functions in LockManager. For example, in veRAACToken.lock:

_lockState.createLock(msg.sender, amount, duration); // Updates _lockState.locks mapping

This updates the _lockState.locks mapping, but not the veRAACToken.locks mapping. The same applies to increase and extend. As a result, the getLockedBalance and getLockEndTime functions always return zero, even if a user has locked tokens.

Impact:

The inconsistent lock data storage leads to the following issues:

  • Incorrect Locked Balance: getLockedBalance always returns 0, even if a user has locked tokens.

  • Incorrect Lock End Time: getLockEndTime always returns 0, even if a user has locked tokens.

Tools Used:

Manual code review.

Recommended Mitigation:

Remove the redundant locks mapping from the veRAACToken contract. All lock information should be stored and managed within the _lockState struct using the LockManager library. Modify getLockedBalance and getLockEndTime to retrieve data from the correct storage location:

// In veRAACToken.sol
- mapping(address => Lock) public locks; // Remove this mapping
function getLockedBalance(address account) external view returns (uint256) {
- return locks[account].amount; // Read from the incorrect mapping
+ return _lockState.locks[account].amount; // Read from _lockState.locks
}
function getLockEndTime(address account) external view returns (uint256) {
- return locks[account].end; // Read from the incorrect mapping
+ return _lockState.locks[account].end; // Read from _lockState.locks
}
Updates

Lead Judging Commences

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

veRAACToken::getLockEndTime and getLockedBalance returns 0 by reading from unused locks mapping instead of _lockState, making lock expiry times unavailable to clients

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

veRAACToken::getLockEndTime and getLockedBalance returns 0 by reading from unused locks mapping instead of _lockState, making lock expiry times unavailable to clients

Support

FAQs

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

Give us feedback!