Testing an On-Chain Task/Reward Orchestrator with Foundry
ProofOrchestrator.sol moves money once a proof is attested. Eight tests, each named for the specific thing it refuses to let happen.
The naming convention is deliberate: every test name states the specific guarantee, not just the function under test, so a failing test in CI output already tells you what broke without opening the file.
| Test | What it refuses to let happen |
|---|---|
| test_submitProof_ alwaysRevertsWithoutARealVerifier | Payment without a real verifier configured — the default state is "pays nothing," not "pays on faith." |
| test_paysOutOnlyAfterAttestation | A prover collecting a reward before the attester has actually attested. |
| test_rejectsProofBytesThat DontMatchTheAttestation | Submitting different proof bytes than the ones the attester actually attested to. |
| test_onlyAttesterCanAttest | Anyone other than the configured attester address calling attest(). |
| test_cannotDoubleFulfill | Claiming the same reward twice for one task. |
| test_onlyTheClaimingProver CanSubmit | A different address than the one that claimed the task submitting a proof for it. |
| test_cannotClaimAnAlready ClaimedTask | Two provers racing to claim the same task and both succeeding. |
| test_cannotClaimOrSubmit ForAnUnknownTask | Referencing a task ID that was never created. |
Notice what's not in this list: nothing here tests that the STARK proof itself is valid, because the contract can't check that — see the trust-boundary post for why. These eight tests cover the access-control and state-machine surface of "who can trigger a payment, and when" — the part that is the contract's job — not the cryptography, which is zkvm-stark's job and is tested separately in Rust.
contracts/lib/forge-std is a git submodule, which is why CI checks it out with submodules: true before running forge test -vv — an easy step to forget when copying this CI job elsewhere, since a missing submodule fails with a confusing "file not found" rather than an obvious submodule error.