Skip to content
Last updated: February 06, 2026

SCWE-156: Missing Emergency Circuit Breaker for Critical Operations

Stable Version v1.0

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

Send Feedback

Relationships

Description

A circuit breaker is a threshold-based or condition-based halt mechanism that stops critical operations when anomalies are detected (e.g., TVL drop >X%, unusual withdrawal volume, oracle deviation). Unlike simple pausability (SCWE-014), a circuit breaker automatically or semi-automatically triggers based on predefined conditions, providing an additional safety layer during attacks or market stress.

Remediation

  • Implement circuit breakers that halt deposits, withdrawals, or swaps when thresholds are exceeded.
  • Use oracle-based triggers (e.g., price deviation) or rate-limit triggers.
  • Ensure the circuit breaker can be reset by governance or after cooldown.

Examples

Vulnerable

pragma solidity ^0.8.0;

contract LendingPool {
    mapping(address => uint256) public balances;
    uint256 public totalDeposits;

    function deposit() external payable {
        balances[msg.sender] += msg.value;
        totalDeposits += msg.value;
    }

    function withdraw(uint256 amount) external {
        require(balances[msg.sender] >= amount, "Insufficient");
        balances[msg.sender] -= amount;
        totalDeposits -= amount;
        (bool ok, ) = msg.sender.call{value: amount}("");
        require(ok, "Transfer failed");
    }
}
Gap: No circuit breaker. A flash loan or oracle attack could drain funds before anyone can pause.

Mitigation

uint256 public maxWithdrawalPerTx = 100 ether;
uint256 public lastWithdrawalTime;
uint256 public constant WITHDRAWAL_COOLDOWN = 1 hours;

function withdraw(uint256 amount) external {
    require(amount <= maxWithdrawalPerTx, "Circuit breaker: amount too high");
    require(block.timestamp >= lastWithdrawalTime + WITHDRAWAL_COOLDOWN, "Cooldown");
    lastWithdrawalTime = block.timestamp;
    // ... rest of logic
}