Core Contracts

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

Inconsistent `totalLocked` Accounting in `withdraw` and `emergencyWithdraw` Functions Leads to Inaccurate Total Locked Amount

Summary:

The withdraw and emergencyWithdraw functions in the veRAACToken contract do not correctly decrement the _lockState.totalLocked counter when users withdraw their locked tokens. While the individual user lock information is deleted, the totalLocked counter, which tracks the total amount of locked tokens in the system, is not updated. This inconsistency leads to an inaccurate totalLocked value, potentially affecting calculations and functionalities that rely on this metric.

Vulnerability Details:

Both the withdraw and emergencyWithdraw functions delete the user's lock information from the _lockState.locks mapping:

// In withdraw() and emergencyWithdraw()
delete _lockState.locks[msg.sender];
delete _votingState.points[msg.sender];

However, neither of these functions decrements the _lockState.totalLocked counter, which is crucial for maintaining an accurate record of the total locked tokens.

// In LockManager.sol
struct LockState {
mapping(address => Lock) locks;
uint256 totalLocked; // This counter is NOT decremented in veRAACToken's withdraw/emergencyWithdraw
// ...
}

This means that after a user withdraws, _lockState.totalLocked will still reflect the withdrawn amount, leading to an overestimation of the actual total locked tokens.

Impact:

The inaccurate totalLocked value can have several negative consequences:

  • Incorrect Boost Calculations: The BoostCalculator likely uses _lockState.totalLocked to calculate boost multipliers. An inflated totalLocked value could lead to incorrect boost calculations, potentially granting users higher or lower boosts than they should receive.

  • Inaccurate APR/APY Calculations: If the protocol calculates APR/APY based on the total locked amount, the inflated totalLocked value will result in incorrect APR/APY representations.

  • Potential Governance Issues: If governance decisions or voting power are related to the total locked amount, the inaccurate totalLocked value could skew the results.

  • UI/UX Issues: User interfaces that display the total locked amount will show an incorrect value, potentially confusing users.

Proof of Concept (PoC):

Scenario: Alice locks 100 tokens. Bob then locks 200 tokens. The _lockState.totalLocked counter is correctly updated to 300. Alice then withdraws her 100 tokens.

  1. Alice Locks: Alice calls lock(100, 365 days). _lockState.totalLocked becomes 100.

  2. Bob Locks: Bob calls lock(200, 365 days). _lockState.totalLocked becomes 300.

  3. Alice Withdraws: Alice calls withdraw(). Her lock information is deleted from _lockState.locks, but _lockState.totalLocked remains at 300.

The _lockState.totalLocked counter should now be 200, but it is incorrectly still 300.

Recommended Mitigation:

Decrement _lockState.totalLocked in both the withdraw and emergencyWithdraw functions after deleting the user's lock information. Retrieve the amount to be decremented from the user's lock struct before it is deleted.

function withdraw() external nonReentrant whenNotPaused {
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
uint256 amount = userLock.amount; // Get the amount BEFORE deleting the lock
// ... other code ...
delete _lockState.locks[msg.sender];
delete _votingState.points[msg.sender];
+ _lockState.totalLocked -= amount; // Decrement totalLocked
// ... rest of the code ...
}
function emergencyWithdraw() external nonReentrant {
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
uint256 amount = userLock.amount; // Get the amount BEFORE deleting the lock
// ... other code ...
delete _lockState.locks[msg.sender];
delete _votingState.points[msg.sender];
+ _lockState.totalLocked -= amount; // Decrement totalLocked
// ... rest of the code ...
}
Updates

Lead Judging Commences

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

veRAACToken::withdraw / emergencyWithdraw doesn't substract the `_lockState.totalLocked`

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

veRAACToken::withdraw / emergencyWithdraw doesn't substract the `_lockState.totalLocked`

Support

FAQs

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

Give us feedback!