Start with an immutable review target
An audit cannot produce reproducible evidence if the target changes during review. Define the repository, exact commit hash, compiler and dependency versions, target networks, deployed addresses if any, and every contract or program included in scope. List generated code and vendor libraries separately so reviewers can distinguish owned logic from dependencies.
Scope exclusions should be as explicit as inclusions. Frontends, backend signers, keeper services, bridges, oracles, indexers, and deployment scripts may change the real attack surface even when they are not part of the core contract review. Recording those boundaries prevents an audit report from being interpreted more broadly than the work performed.
Map authority and irreversible actions
Document owners, multisigs, upgrade authorities, pausers, fee setters, minters, treasury roles, allowlists, emergency paths, and any function that can move assets or change accounting. For each role, state who controls it at launch, how keys are protected, whether a delay applies, and how authority can be revoked or transferred.
Reviewers also need the expected invariants: what must always remain true about balances, shares, collateral, rewards, supply, permissions, and state transitions. Business rules expressed as invariants make manual review, fuzzing, and property tests more useful than a generic vulnerability checklist.
Include integrations and failure assumptions
List tokens, price feeds, bridges, routers, callbacks, signature standards, account-abstraction components, off-chain services, and cross-chain message paths. State assumptions about decimals, fee-on-transfer behavior, rebasing, stale prices, finality, replay protection, callback behavior, and third-party downtime.
A security review should examine how the system fails, not only how it succeeds. Define expected behavior when an oracle is stale, an RPC is unavailable, a keeper misses a job, a token behaves unexpectedly, a transaction is partially executed, or an administrator needs to pause a subsystem.
Agree on findings, remediation, and retest
Before work begins, define severity criteria, report format, communication channel, disclosure handling, expected patch window, and what a retest covers. A retest should reference the remediation commit and classify each original finding as resolved, partially resolved, accepted, or still open. New features added after the locked commit require separate review.
The final acceptance package should include the scope and commit, methods used, findings, remediation status, known limitations, test evidence, and any deployment-specific checks. An audit reduces technical uncertainty; it does not guarantee that a system is free of defects or operational risk.
Prepare a release evidence checklist
Treat build, test, deploy, and public verification as separate release steps. Capture deterministic build output, automated tests, static analysis or fuzz results, deployment transaction receipts, verified source links, final role assignments, monitoring configuration, and an incident runbook. This evidence lets operators confirm that the reviewed code is the code actually released.
Submit Project Brief