Core Contracts

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

`EMERGENCY_DELAY` Is Declared but Never Enforced for Emergency Actions

TimelockController.sol

Overview

The contract defines:

uint256 public constant EMERGENCY_DELAY = 1 days;

But in the emergency flow:

  1. scheduleEmergencyAction(bytes32 id)

    • Simply does _emergencyActions[id] = true; and emits EmergencyActionScheduled(id, block.timestamp);

    • Does not set any timestamp or wait period for the operation.

  2. executeEmergencyAction(...)

    • Checks if (!_emergencyActions[id]) revert ...;

    • If true, it proceeds immediately to call each target address with no time check.

No logic references EMERGENCY_DELAY. The net result is that once scheduleEmergencyAction(id) is called, an “emergency action” can be executed instantly—contrary to the doc that references a 1‑day “Delay for emergency actions.”

Attack/PoC

A minimal demonstration:

// 1) Admin calls scheduleEmergencyAction(id) at T0.
timelock.scheduleEmergencyAction(emergencyOperationId);
// 2) Immediately calls executeEmergencyAction(...)
timelock.executeEmergencyAction(targets, values, calldatas, predecessor, salt);
// => Succeeds with no forced wait, ignoring the doc-stated 1 day delay

Because there is no code referencing block.timestamp + EMERGENCY_DELAY, the function does not revert or wait.

Impact

  • Contrary to Documentation
    The doc claims a 1-day forced wait for emergency calls. In reality, the code allows immediate scheduling and execution, making emergency calls effectively unstoppable or with zero timelock.

  • Governance & Security Implications
    If the protocol relies on a 1-day lead time before powerful “emergency” moves can occur, the current code does not provide that cushion. Attackers or compromised roles might exploit this to push changes instantly.

  • Mismatch & Confusion
    Developers or auditors see EMERGENCY_DELAY = 1 days but find no usage, leading to confusion or false assumptions about how quickly emergency actions can be triggered.

Recommendation

  1. Enforce the Delay

    • In scheduleEmergencyAction, store a timestamp (e.g. _emergencyTimestamps[id] = block.timestamp + EMERGENCY_DELAY;).

    • In executeEmergencyAction, require block.timestamp >= _emergencyTimestamps[id] to ensure the 1‑day wait.

  2. Remove or Document

    • If the design is to allow truly instant emergency actions, remove or rename EMERGENCY_DELAY, clarifying that no forced wait is actually imposed.

    • Alternatively, rename it “emergencyNoWait” or document that a future version might enforce the delay.

  3. Confirm Roles

    • Because “emergency calls” can bypass normal timelock constraints, carefully ensure that only the correct role (EMERGENCY_ROLE) can call it—and if the protocol’s doc states a 1-day wait, that must be coded.

Updates

Lead Judging Commences

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

TimelockController emergency actions bypass timelock by not enforcing EMERGENCY_DELAY, allowing immediate execution

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

TimelockController emergency actions bypass timelock by not enforcing EMERGENCY_DELAY, allowing immediate execution

Support

FAQs

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

Give us feedback!