Skip to content
This guide targets Fe 26.4. Fe is not production-ready. Install Fe 26.4

Assertions

Use assert!(condition) to stop execution when a condition is false. In a contract call, a revert rolls back state changes and logs made by that call, including its successful subcalls.

Assertions can validate inputs before changing state. An optional string explains the failure:

fn withdraw(balance: u256, amount: u256) -> u256 {
assert!(amount > 0, "amount must be positive")
assert!(amount <= balance, "insufficient balance")
balance - amount
}
#[test]
fn withdrawal_succeeds() {
assert!(withdraw(balance: 100, amount: 40) == 60)
}
#[test(should_revert, selector = 0x08c379a0)]
fn withdrawal_rejects_insufficient_balance() {
let _ = withdraw(balance: 10, amount: 11)
}

The condition must be a bool. The message must be a string literal, not a const or other String value, and not a Rust-style formatting argument list. Both forms are available without an import.

The two forms revert with different payloads:

FormRevert payload
assert!(condition)Solidity Panic(uint256) with code 0x01
assert!(condition, "message")Solidity Error(string) (selector 0x08c379a0) with the message

Use a short assertion for an invariant or a simple precondition. When callers need structured failure information, define a custom error and use revert_error. For an operation whose failure the caller should handle locally, return Result.

Assertions are also the basis of unit tests. A bare #[test(should_revert)] accepts any revert. Add selector = ... to require a particular error selector, or panic = ... to require a particular Panic code; see Checking the revert reason:

#[test(should_revert, panic = 0x01)]
fn bare_assert_panics() {
let amount: u256 = 0
assert!(amount > 0)
}
#[test(should_revert, selector = 0x08c379a0)]
fn message_assert_reverts_with_error_string() {
let amount: u256 = 0
assert!(amount > 0, "amount must be positive")
}

Neither form checks the message text or which assertion failed, so keep negative tests focused on one invalid input and give them otherwise valid setup.

core::panic_code(code) reverts on the EVM with the Solidity Panic(uint256) payload. The core::panics::PANIC_* constants provide standard codes; native targets trap instead. Bounds-checked core::ptr access reports Panic(0x32) for an invalid index.

#[test(should_revert)]
fn explicit_panic() {
core::panic_code(0x32)
}