Core Contracts

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

Global Locked Token Count Not Decremented on Withdrawals

Summary

The withdraw() function in veRaacToken.sol allows users to unlock their previously locked RAAC tokens after the lock period expires by deleting their lock data, burning their veTokens, and transferring the original RAAC tokens back. However, while the locking process increases the global locked amount, the withdrawal process merely deletes the user's lock details without decrementing the global total of locked tokens.

Vulnerability Details

When a user calls withdraw(), the function performs the following steps:

  1. Validation:
    It checks that a lock exists for the caller and that the current timestamp is past the lock expiry.

  2. State Clearing:
    The function deletes the user's lock data from _lockState.locks and associated voting power checkpoints from _votingState.points.

  3. Checkpoint Update:
    It updates the user's checkpoint to zero to reflect the loss of voting power.

  4. Token Burn and Transfer:
    The function burns the user's veTokens (representing voting power) and transfers the locked RAAC tokens back to the user.

While these operations correctly handle the user-specific state, the function does not adjust any global variable that tracks the total locked amount. This means that the global metric remains artificially high even after tokens are withdrawn.

Proof of Concept

Imagine a user locks 100 RAAC tokens, increasing the global locked amount by 100 tokens. Later, when the user withdraws, the function clears their lock and returns 100 tokens to the user, but the global locked total is not reduced. If several users follow this pattern, the overall locked amount reported by the protocol will be significantly higher than the actual tokens locked, leading to misaligned incentives and inaccurate governance calculations.

Impact

Inaccurate Global Metrics:
The total locked amount remains overstated, potentially affecting calculations for voting power, rewards, and governance decisions.

  • Economic Imbalance:
    Over time, if many users withdraw their tokens without the global counter being updated, the protocol may misallocate rewards or fees based on inflated locked totals.

  • Reduced Transparency:
    Stakeholders relying on global locked metrics may be misled about the actual level of token commitment within the protocol.

Tools Used

Manual review

Recommendations

  • Update Global Locked Counter:
    Modify the withdrawal logic to decrement the global locked total by the withdrawn amount. For instance, if _lockState.totalLocked tracks the cumulative locked tokens, ensure that it is reduced accordingly when a withdrawal occurs.

  • Ensure Consistency:
    Review the LockManager library to confirm that all operations (locking, increasing, extending, and withdrawing) consistently update the global state variables.

  • Implement Unit Tests:
    Develop comprehensive tests that simulate locking and withdrawing tokens to verify that the global locked amount accurately reflects the sum of all active locks.

By updating the global locked counter on withdrawal, the protocol will maintain accurate metrics, ensuring that reward and governance calculations remain fair and transparent.

Updates

Lead Judging Commences

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

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

inallhonesty Lead Judge 4 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.