diff --git a/.github/workflows/hunter-invariants.yml b/.github/workflows/hunter-invariants.yml new file mode 100644 index 0000000..87768b7 --- /dev/null +++ b/.github/workflows/hunter-invariants.yml @@ -0,0 +1,42 @@ +# Drop this into a Uniswap v4 hook repo at `.github/workflows/hunter-invariants.yml` to gate every +# PR on Hunter's value-conservation invariant suite. It auto-discovers every hook in your repo, +# generates a harness for each, runs them under Foundry, and FAILS the PR if any invariant breaks OR +# the run was too thin to be meaningful (vacuous coverage -- e.g. every fuzzed swap reverted). +# +# Zero per-hook config: point `scan` at your source dir and Hunter finds the hooks itself. Hooks with +# bespoke constructor dependencies (an oracle / vault / AVS / liquidation protocol) are auto-stood-up +# (the dependency is mocked and its returns are fuzzed); a hook whose src needs IR codegen is recompiled +# with --via-ir automatically. A hook that genuinely needs hand-config is reported NEEDS_CONFIG and +# skipped (never a fabricated pass), so it can't block your PR. +name: hunter-invariants +on: + pull_request: + workflow_dispatch: + +# The action posts a sticky results comment on the PR (the green/red "Safety Floor" table). +# That needs write access to pull requests; contents:read is for the checkout. +permissions: + contents: read + pull-requests: write + +jobs: + invariants: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive # pull in v4-core / forge-std so `forge test` resolves + + - uses: hunterinvariants/hunter-invariants/actions/v4-invariants@8a940f57c0d4efda2eb234f097e6ece946715c44 # v3 + with: + scan: src # auto-discover + gate EVERY hook under src/ -- no per-hook config + # runs: 256 # optional -- lower (e.g. 50) for faster PRs, raise for nightly + # depth: 500 + +# ── Prefer to target ONE hook explicitly instead of scanning? Drop `scan:` and use `hook:` (+ `impl:` +# if it's an abstract base whose concrete deploy target is a *Mock): +# +# - uses: hunterinvariants/hunter-invariants/actions/v4-invariants@8a940f57c0d4efda2eb234f097e6ece946715c44 # v3 +# with: +# hook: src/MyHook.sol +# impl: src/mocks/MyHookMock.sol # omit if your hook is concrete