Skip to content

feat(invariant): add fail_on_assert for Solidity assert failures#13519

Closed
aviggiano wants to merge 5 commits intofoundry-rs:masterfrom
aviggiano:feat/invariant-fail-on-assert
Closed

feat(invariant): add fail_on_assert for Solidity assert failures#13519
aviggiano wants to merge 5 commits intofoundry-rs:masterfrom
aviggiano:feat/invariant-fail-on-assert

Conversation

@aviggiano
Copy link
Copy Markdown

@aviggiano aviggiano commented Feb 23, 2026

Summary

  • add [invariant].fail_on_assert to InvariantConfig (default false)
  • fail invariant campaigns on Solidity assert failures even when fail_on_revert = false
    • Panic(0x01)
    • legacy invalid-opcode assertion behavior (InstructionResult::InvalidFEOpcode)
  • keep behavior unchanged for:
    • require/generic reverts
    • non-assert panics (e.g. Panic(0x11))
    • vm.assert* / GLOBAL_FAIL_SLOT semantics
  • classify fail_on_assert failures as BrokenInvariant (not generic Revert)
  • apply the same condition in replay/shrink paths so persisted failures stay reproducible

Implementation Notes

  • config model
    • crates/config/src/invariant.rs
  • runtime decision paths
    • crates/evm/evm/src/executors/invariant/result.rs
    • crates/evm/evm/src/executors/invariant/mod.rs
  • replay/shrink parity
    • crates/evm/evm/src/executors/invariant/shrink.rs
    • crates/forge/src/runner.rs
  • propagated case data
    • crates/evm/evm/src/executors/invariant/error.rs
  • config snapshots
    • crates/forge/tests/cli/config.rs
  • regression tests
    • crates/forge/tests/cli/test_cmd/invariant/common.rs

Tests

  • cargo +1.91.0 test -p foundry-evm invariant::result::tests --lib --locked
  • cargo +1.91.0 test -p forge --test cli fail_on_assert --locked
  • cargo +1.91.0 test -p forge --test cli invariant_ignore_assert_panic_when_flag_off --locked
  • cargo +1.91.0 test -p forge --test cli test_default_config --locked

Closes #13322

@aviggiano
Copy link
Copy Markdown
Author

Wait a sec, this is not exactly what we need

I'm testing this branch on scfuzzbench/scfuzzbench-canary#2 but it is reporting invariant_noop as a root cause for assertion failure, when in reality it should report counter_increment

I'll try to fix this

@aviggiano
Copy link
Copy Markdown
Author

Still not feature parity with medusa, since we will only see assertion failures on logs. I'd also see them as "first class citizen" in metrics JSON

@0xalpharush
Copy link
Copy Markdown
Contributor

I rebased #12587 and got assertion failures working on this canary (with shrinking/replay working w/o changing from an assertion to invariant). I also updated the logs and trace format

https://github.com/0xalpharush/foundry/tree/fail_on_assert

@aviggiano
Copy link
Copy Markdown
Author

hey, thanks for the contribution

This looks really good overall, with one caveat: it is picking up assert(...) but not Forge cheatcode assertions vm.assert*

So we need to think whether we'd want to support both out of the box (I think so)

@0xalpharush
Copy link
Copy Markdown
Contributor

It is checking this slot but maybe there's some weird interaction with assertions_revert. or it's not the right way..
2cf1340#diff-6547e74fc7387bb7d95a9612a3a04ba728664f9b0a359c598fd6bdb64b2ce118R702-R720

@grandizzy
Copy link
Copy Markdown
Collaborator

addressed in #14275

@grandizzy grandizzy closed this Apr 24, 2026
@github-project-automation github-project-automation Bot moved this to Done in Foundry Apr 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Report assertion failures as broken invariants

3 participants