How the smart contracts are tested.
Every contract behind the Pigfox demos passes four independent engines and a live-chain rehearsal before it touches real infrastructure. This is the pipeline.
One property set. Three engines.
test/Properties.sol defines six invariants — funds equal obligations, the arbiter can never be credited, state transitions stay legal, obligations never exceed funding, nullifiers never repeat, and the ledger stays consistent. Foundry, Echidna, and Medusa all execute the same file, so a property cannot hold in one engine and silently not exist in another.
The stages.
- Foundry. Unit and invariant tests on a pinned toolchain — 115 tests across 7 suites at last count, all passing, none skipped. The formatting gate runs on a deliberately pinned compiler version so an unrelated upstream release cannot turn an unchanged tree red.
- Slither. Static analysis on every push, failing the build on low-severity findings and up. The exclusions are written down in the repository rather than silently configured away.
- Echidna and Medusa. Two independent fuzzers hammer the same six properties. Both assert they registered exactly six — because a stale build artifact once silently shrank the property set and reported a smaller green run. The harness guards itself against testing less than you think it does.
- Live chain. Deployment, a UUPS upgrade, and nine AI-arbitrated dispute settlements executed on Base Sepolia. Upgrades are rehearsed first against a fork of live chain state, then broadcast, then verified on-chain — every settlement checked for its resolved state, a successful transaction, and an event carrying the arbiter's rationale.
Coverage without asterisks.
The gate requires 100% line, statement, branch, and function coverage on every file under src/ — with exactly one documented exclusion: the verifier generated verbatim by snarkjs from the proving key. Generated code is excluded by name, not hidden inside a percentage. The check fails on a report it cannot parse, so a format change cannot pass by default.