Core Contracts

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

scheduleEmergencyAction() Allows Any actionId, But withEmergencyDelay Only Accepts EMERGENCY_WITHDRAW_ACTION on veRAACToken.sol

Summary

The scheduleEmergencyAction() function allows the admin to input any actionId, but the withEmergencyDelay modifier only works with specific pre-defined action IDs (EMERGENCY_WITHDRAW_ACTION, EMERGENCY_UNLOCK_ACTION).

This creates a potential issue where the admin may mistakenly schedule an invalid actionId that can never be executed, leading to locked emergency actions that cannot be undone.

Vulnerability Details

Admin Can Schedule Any actionId

function scheduleEmergencyAction(bytes32 actionId) external onlyOwner {
_emergencyTimelock[actionId] = block.timestamp;
emit EmergencyActionScheduled(actionId, block.timestamp + EMERGENCY_DELAY);
}
  • The function accepts any bytes32 actionId and stores it in _emergencyTimelock.

  • There is no validation to ensure the actionId matches the predefined emergency actions (EMERGENCY_WITHDRAW_ACTION or EMERGENCY_UNLOCK_ACTION).

  • If the admin accidentally enters an incorrect actionId, the system will store it but never allow execution.

withEmergencyDelay Only Allows Predefined actionId Values.

This modifier is only applied in two functions:

function enableEmergencyWithdraw() external onlyOwner withEmergencyDelay(EMERGENCY_WITHDRAW_ACTION) {}
function executeEmergencyUnlock() external onlyOwner withEmergencyDelay(EMERGENCY_UNLOCK_ACTION) {}

Problem

  • If an incorrect actionId is scheduled, it can never be executed because no function calls withEmergencyDelay(actionId).

  • The wrong actionId will remain stored in _emergencyTimelock indefinitely, leading to admin confusion and potential governance failures.

Impact

  • Incorrect actionId entries remain in _emergencyTimelock indefinitely, causing admin confusion.

  • If the admin assumes an incorrect action was scheduled properly, they may fail to execute a critical emergency action when needed.

  • Storing unused actionId entries wastes contract storage.

Tools Used

Manual review

Recommendations

Validate actionId in scheduleEmergencyAction()

function scheduleEmergencyAction(bytes32 actionId) external onlyOwner {
// . validate actionId
if (actionId != EMERGENCY_WITHDRAW_ACTION) {
revert InvalidEmergencyAction();
}
_emergencyTimelock[actionId] = block.timestamp;
emit EmergencyActionScheduled(actionId, block.timestamp + EMERGENCY_DELAY);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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