Invariant Macros#
Invariant macros are used to define intentional checks in your fuzz tests. When an invariant fails, it is counted and collected separately from unexpected panics, and fuzzing continues to find more issues.
For conceptual guidance on how and when to use invariants, see Invariants and Assertions.
Invariants vs Regular Panics
Only invariant! failures are collected and allow fuzzing to continue. Regular panics (like unwrap() on None) are treated as bugs in your fuzz test and will crash the worker immediately.
invariant!#
Checks a boolean condition. The most general-purpose invariant macro.
Failure message (default):
Example:
invariant!(account.is_initialized);
invariant!(balance > 0, "Balance must be positive, got {}", balance);
invariant_eq!#
Checks that two expressions are equal. Displays actual values on failure.
Failure message (default):
Example:
invariant_eq!(balance_after, balance_before - amount);
invariant_eq!(account.owner, program_id, "wrong owner");
invariant_ne!#
Checks that two expressions are not equal. Displays the shared value on failure.
Failure message (default):
Example:
invariant_ne!(owner, Pubkey::default());
invariant_ne!(balance_after, balance_before, "balance should have changed");
invariant_gt!#
Checks that the first expression is strictly greater than the second.
Failure message (default):
Example:
invariant_gt!(balance, 0);
invariant_gt!(supply_after, supply_before, "supply should increase after mint");
invariant_gte!#
Checks that the first expression is greater than or equal to the second.
Failure message (default):
Example:
invariant_gte!(balance, minimum_balance);
invariant_gte!(lamports, rent_exempt, "account not rent-exempt");
invariant_lt!#
Checks that the first expression is strictly less than the second.
Failure message (default):
Example:
invariant_lte!#
Checks that the first expression is less than or equal to the second.
Failure message (default):
Example: