Core Contracts

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

Checkpoint Not Updated During Emergency Withdrawal

Description

The emergencyWithdraw function in the veRAACToken.sol contract does not update the checkpoint state after a user withdraws their tokens during an emergency. The checkpoint system is responsible for maintaining historical voting power data, and failing to update it can lead to inconsistencies in governance and voting power calculations.

Affected Code

function emergencyWithdraw() external nonReentrant {
if (emergencyWithdrawDelay == 0 || block.timestamp < emergencyWithdrawDelay)
revert EmergencyWithdrawNotEnabled();
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
if (userLock.amount == 0) revert NoTokensLocked();
uint256 amount = userLock.amount;
uint256 currentPower = balanceOf(msg.sender);
delete _lockState.locks[msg.sender];
delete _votingState.points[msg.sender];
// @audit-issue checkpoint is not updated
_burn(msg.sender, currentPower);
raacToken.safeTransfer(msg.sender, amount);
emit EmergencyWithdrawn(msg.sender, amount);
}

Vulnerability Details

The checkpoint system tracks historical voting power at specific points in time. When a user withdraws their tokens during an emergency, the emergencyWithdraw function does not update the checkpoint state to reflect the withdrawal. This results in the following issues:

  1. Inconsistent Voting Power History: Historical voting power data will be incorrect, as the checkpoint does not reflect the withdrawal.

  2. Potential Exploitation: Users could withdraw their tokens during an emergency and still retain their voting power in historical records, potentially allowing them to manipulate governance or reward systems unfairly.

  3. Data Integrity: The integrity of the voting power data is compromised, as the checkpoint system fails to accurately reflect the state of the system after an emergency withdrawal.

Tools Used

Manual Review

Recommended Mitigation Steps

Update the checkpoint state in the emergencyWithdraw function to ensure that the user's voting power is correctly set to zero after the withdrawal. Add the following line before burning the tokens:

_checkpointState.writeCheckpoint(msg.sender, 0);

The updated function should look like this:

function emergencyWithdraw() external nonReentrant {
if (emergencyWithdrawDelay == 0 || block.timestamp < emergencyWithdrawDelay)
revert EmergencyWithdrawNotEnabled();
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
if (userLock.amount == 0) revert NoTokensLocked();
uint256 amount = userLock.amount;
uint256 currentPower = balanceOf(msg.sender);
delete _lockState.locks[msg.sender];
delete _votingState.points[msg.sender];
// Update checkpoints to reflect the withdrawal
_checkpointState.writeCheckpoint(msg.sender, 0);
_burn(msg.sender, currentPower);
raacToken.safeTransfer(msg.sender, amount);
emit EmergencyWithdrawn(msg.sender, amount);
}
Updates

Lead Judging Commences

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

veRAACToken::emergencyWithdraw doesn't update checkpoint - innacurate historical voting power, inconsistent state

Support

FAQs

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