Skip to main content
Sigvex

Assert Violation

Detects reachable assert() statements that indicate invariant violations and potential logic bugs in smart contracts.

Assert Violation

Overview

Remediation Guide: How to Fix Assert Violation

The assert violation detector identifies reachable assert() statements in smart contracts. Unlike require(), which validates external inputs, assert() checks internal invariants that should never be false. A reachable assertion failure means the contract’s own logic can reach a state the developer believed impossible — a strong indicator of bugs.

In Solidity versions before 0.8.0, a failed assert() emits the INVALID opcode (0xFE), consuming all remaining gas. In Solidity 0.8.0 and later, it emits a Panic(0x01) error code that still reverts but refunds unused gas.

Why This Is an Issue

A triggered assertion means the contract has entered a state that violates its own assumptions. Depending on what invariant is broken, this can lead to locked funds, incorrect state transitions, or denial of service. In pre-0.8 contracts, the gas-consuming INVALID opcode makes assertion failures particularly expensive for users, and attackers can exploit this for gas griefing.

How to Resolve

// Before: Reachable assertion — invariant can be violated
function withdraw(uint256 amount) external {
    balances[msg.sender] -= amount;
    assert(totalSupply >= amount); // Can fail if balances and totalSupply diverge
    totalSupply -= amount;
    payable(msg.sender).transfer(amount);
}

// After: Guard with require(), use assert() only for true invariants
function withdraw(uint256 amount) external {
    require(balances[msg.sender] >= amount, "Insufficient balance");
    require(totalSupply >= amount, "Supply underflow");
    balances[msg.sender] -= amount;
    totalSupply -= amount;
    payable(msg.sender).transfer(amount);
    assert(totalSupply == _computeExpectedSupply()); // True invariant check
}

Detection Methodology

  1. INVALID opcode scan: Identifies 0xFE bytes in pre-0.8 bytecode that correspond to failed assert() calls.
  2. Panic code detection: In 0.8+ bytecode, detects Panic(0x01) revert patterns (selector 0x4e487b71 with code 0x01).
  3. Reachability analysis: Traces control flow to determine whether assert paths are reachable under valid inputs.
  4. Compiler version inference: Uses bytecode metadata to distinguish assert semantics between Solidity versions.

Limitations

False positives: Assertions that are theoretically reachable in the CFG but unreachable due to external constraints (e.g., token supply caps enforced by other contracts) may be flagged. False negatives: Custom assertion patterns that do not use the standard assert() built-in are not detected.

References