Skip to content
Last updated: December 19, 2024

SCWE-015: Lack of Emergency Stop Mechanism

Content in BETA

This content is in beta and still under active development, so it is subject to change any time (e.g. structure, IDs, content, URLs, etc.).

Send Feedback

Relationships

  • CWE-693: Protection Mechanism Failure
    CWE-693

Description

A Lack of Emergency Stop Mechanism refers to the absence of a built-in feature in a smart contract that allows for halting or pausing critical operations during emergencies. This mechanism is essential for mitigating risks like a discovered vulnerability, unexpected behavior, or a malicious attack. Without this safeguard, the contract may continue executing malicious actions or suffer irreversible damage. The ability to stop critical functions provides an important recovery measure in scenarios where an exploit is detected or control needs to be regained.

Key risks: - Continuous execution of harmful or malicious actions without control. - Difficulty in recovering from unexpected failures. - Increased vulnerability to hacks or exploitation.

Remediation

  • Implement a pausable contract pattern: Use the Pausable contract from the OpenZeppelin library to implement a mechanism that allows authorized users (e.g., the owner or a governance entity) to pause and unpause certain critical contract functions.
  • Limit emergency stop to critical functions: Ensure that only critical functions can be paused to minimize the impact on the rest of the system's operation.
  • Implement role-based access control: Use a role-based mechanism to control who has the ability to pause or unpause functions, reducing the risk of unauthorized access.

Samples

Lack of Emergency Stop Mechanism Example

pragma solidity ^0.8.0;

contract NoEmergencyStop {
    address public owner;
    uint public criticalValue;

    constructor() {
        owner = msg.sender;
    }

    // This function is critical and lacks an emergency stop mechanism
    function updateCriticalValue(uint newValue) public {
        require(msg.sender == owner, "Only the owner can update this value");
        criticalValue = newValue;
    }
}
In the NoEmergencyStop contract, there is no way to stop or pause critical operations, which makes it vulnerable to continued exploitation if an issue arises.

Fixed: Emergency Stop Mechanism Example

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/security/Pausable.sol";

contract EmergencyStopExample is Pausable {
    address public owner;
    uint public criticalValue;

    constructor() {
        owner = msg.sender;
    }

    // Critical function that can be paused in case of emergency
    function updateCriticalValue(uint newValue) public whenNotPaused {
        require(msg.sender == owner, "Only the owner can update this value");
        criticalValue = newValue;
    }

    // Emergency stop function to pause the contract
    function emergencyStop() public {
        require(msg.sender == owner, "Only the owner can stop the contract");
        _pause();  // Pauses the contract
    }

    // Emergency restart function to unpause the contract
    function resumeOperations() public {
        require(msg.sender == owner, "Only the owner can resume the contract");
        _unpause();  // Resumes the contract
    }
}
The EmergencyStopExample contract implements the Pausable pattern, which allows the contract owner to pause and unpause critical functions using the emergencyStop and resumeOperations functions. This ensures that if a vulnerability is discovered or a critical issue occurs, the contract can be halted temporarily to prevent further damage.