Skip to content
Last updated: March 11, 2025

SCWE-067: Assert Violation

Stable Version v0.0.1

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

Send Feedback

Relationships

Description

In Ethereum smart contracts, assertions (assert) are commonly used for internal consistency checks and to prevent erroneous states. However, if not used correctly, they can lead to unexpected behavior. When an assert statement fails, it reverts the entire transaction, and all changes made in the transaction are reverted. This can be problematic if it is used for conditions that can be expected during normal contract execution.

Using assert for conditions that can occur under normal circumstances (e.g., user inputs or contract logic) may cause unnecessary reverts and loss of gas. It’s important to reserve assert for critical errors, such as invariants and internal state checks that should never fail.

Remediation

To avoid unnecessary assertion failures, use require for input validation and conditions that can reasonably fail. assert should only be used for internal error detection and state validation that should never happen, as it signals a critical issue if violated.

Vulnerable Contract Example

contract Vulnerable {
    uint public balance;

    constructor() {
        balance = 100;
    }

    function withdraw(uint amount) public {
        assert(balance >= amount);  // Assert violation on user input
        balance -= amount;
    }
}

Fixed Contract Example

contract Secure {
    uint public balance;

    constructor() {
        balance = 100;
    }

    function withdraw(uint amount) public {
        require(balance >= amount, "Insufficient balance");  // Use require for expected conditions
        balance -= amount;
    }
}