certora
Installation
SKILL.md
Certora Formal Verification
Write mathematical proofs that your smart contracts are correct for ALL possible inputs. Certora translates Solidity + CVL specifications into SMT formulas and exhaustively verifies them — no sampling, no random fuzzing, full coverage of the state space.
What You Probably Got Wrong
LLMs confuse CVL with Solidity, hallucinate syntax, and miss the fundamental workflow. Fix these blind spots first.
- CVL is NOT Solidity — It is a separate language (Certora Verification Language) with its own syntax, types, and semantics. You cannot use Solidity expressions like
abi.encodeorkeccak256in CVL. CVL hasmethodsblocks,ruledeclarations,invariant,ghost, andhook— none of which exist in Solidity. - Certora requires an API key — The Prover runs on Certora's cloud infrastructure. You need a
CERTORAKEYenvironment variable. Academic and open-source projects get free access. Commercial pricing is per-verification-minute. - Counter-examples are the key output — When a rule fails, Certora produces a concrete counter-example showing exact call sequences, storage values, and variable assignments that violate your property. Reading these is the core skill — writing specs is secondary.
- Verification is exhaustive, not sampling — Unlike fuzz testing (Foundry, Echidna) which tests random inputs, Certora proves properties hold for ALL possible inputs, ALL possible call sequences, and ALL possible storage states. A passing rule means no counter-example exists.
satisfyis NOTassert—satisfychecks reachability (can this state be reached?).assertchecks universality (does this always hold?). Confusing them produces vacuously passing specs.requirein CVL constrains the prover, not the contract — A CVLrequirenarrows the search space. Over-constraining with too manyrequirestatements makes rules vacuously true (they pass because no valid execution exists). Userule_sanityto catch this.- Loops need explicit bounds — The Prover unrolls loops. Without
--loop_iter Nin your config, loops default to 1 iteration. Most real contracts need 3-7. Too high and verification times explode. mathintis unbounded — CVL'smathinttype has no overflow. Use it for arithmetic in specs to avoid reasoning about overflow in the spec itself (the contract still has its Solidity overflow behavior).- Invariants use induction, not enumeration — Certora proves invariants by assuming they hold at state N and proving they hold at state N+1. The base case (constructor) is checked separately. A failing invariant often means your
preservedblock is missing assumptions.