The Pre-Audit Preparation Checklist
An audit is expensive senior time on a clock. Every hour your auditors spend figuring out how to build the project, or working out what a function is supposed to do, is an hour they are not spending on bugs. Good preparation routinely changes the outcome of an engagement, because it moves the reviewers’ attention from onboarding to the parts of the system that can actually break. Work through this checklist before your start date.
Freeze and document the scope
- Pick a commit and freeze it. Auditing a moving target wastes everyone’s time, and a finding written against code that has since changed is hard to act on. Tag the exact commit under review.
- List in-scope and out-of-scope files explicitly. Ambiguity here is where coverage gaps hide. If a dependency or an upgrade path is out of scope, say so, so nobody assumes someone else is looking at it.
- Write the threat model down. Name the actors and what each is trusted to do: admins, multisig signers, oracles, sequencers, relayers, provers. State the trust boundary explicitly, because most high-severity findings live where a component is trusted more than it should be.
- State the value at risk and the worst realistic outcome, so severity discussions later have a shared reference.
Make the code buildable and runnable in minutes
- One-command build from a clean checkout, documented in the README and tested on a machine that is not yours.
- One-command test run, with instructions for any setup that is not obvious.
- Pin dependencies and the toolchain. Lock compiler versions, library versions, and the proving-system or framework version. “Works on my machine” costs auditor hours that should go to review.
- Provide a working local deployment or example if the system is hard to stand up, plus seed data or a script that exercises the main flows.
Document what the system is supposed to do
This is the part of preparation that pays back the most, because auditors hunt for the gap between what the code does and what it is meant to do.
- Architecture overview. A diagram and a few paragraphs on how the components fit together and where value and trust cross between them.
- Invariants and security properties, written out plainly. The sum of balances always equals total supply. A proof verifies only if the witness is valid. No user can withdraw more than they deposited. Every circuit signal is constrained. State machine transitions are total and ordered. These statements are what a reviewer tries to falsify, so the more precisely you write them, the harder they have to look.
- Specs for the cryptography. For ZK or protocol code, document the scheme, the parameters, the assumptions you rely on, and the soundness and completeness claims. If you depend on a trusted setup, a hash being collision resistant, or a transcript being bound correctly, say so.
- Known issues and prior findings. Share earlier audit reports and anything you already suspect. Hiding these only pays the budget to rediscover them.
Raise your own coverage first
The cheapest bugs to catch are the ones you find before the audit starts.
- Unit and integration tests for the core flows, with real coverage on the value-bearing paths rather than a headline percentage.
- Property and invariant tests. Use stateful fuzzing where the toolchain supports it (for example Foundry invariant tests, Echidna, or Medusa for Solidity) to attack the invariants you wrote down above.
- Static analysis and linters run and triaged, so the auditor is not spending time reporting what Slither or a compiler warning already flags.
- An internal review pass by someone other than the author, which catches the assumptions the author cannot see.
Prepare the people, not just the code
- Name a primary point of contact who can answer design questions within hours, not days. Questions left unanswered turn into assumptions, and a wrong assumption can hide a real bug or invent a false one.
- Schedule a kickoff walkthrough so the team can explain the architecture live and the auditors can ask where the bodies are buried.
- Agree on a findings channel and a severity scale up front, so a disagreement about whether something is high or medium does not turn into a process argument mid-engagement.
- Block time for fixes and a re-review in the schedule, not just the initial pass. Fixes introduce regressions, and the re-review is where you catch them.
Why this matters. Auditors are limited by time, not by willingness. Preparation converts onboarding hours into bug-finding hours. A team that hands over a frozen, buildable, well-documented codebase with clear invariants and a written threat model gets a materially deeper audit than one that does not, for the same money.
Once you are prepared, see how to choose the right auditor for your scope, and consider an ongoing security harness to cover the code as it changes.