Skip to content

Pre-audit checklist

Smart contract audit checklist

The checks I run before a review starts. Fix these first and the paid audit spends its time on real bugs instead of hygiene.

Thirty-two checks, grouped the way an attacker reads a codebase. None of them is a substitute for a review, but every one you fail is a finding an auditor would have to spend paid time writing up.

1. Access control

  1. Every state-changing function has an explicit caller check, or a documented reason it does not need one.
  2. Roles cannot escalate. No role can grant itself a stronger role without a timelock or a multisig.
  3. Initializers run once, on the implementation and the proxy, and cannot be front-run at deploy.
  4. Pause and emergency paths are tested, and unpausing cannot skip accounting or leave stale state.

2. External calls and reentrancy

  1. State is updated before external calls, or a reentrancy guard covers every entry point that reads it.
  2. Read-only reentrancy is considered for functions that read pool state during a callback.
  3. Token callbacks cannot re-enter a half-updated state: ERC-777 hooks, ERC-1155 receivers, native ETH transfers.
  4. Failed external calls are handled. A low-level call that returns false is not a success.

3. Accounting and math

  1. Rounding always favours the protocol, and the direction is documented for deposits and withdrawals.
  2. Share price cannot be manipulated by a first depositor, a donation, or a direct transfer into the vault.
  3. Fee-on-transfer and rebasing tokens are either supported explicitly or rejected at the door.
  4. An invariant test proves the sum of user balances equals the contract balance after every operation.

4. Oracles and prices

  1. Staleness checks exist for every feed, with a documented heartbeat and a revert or fallback path.
  2. Decimals and scaling are handled for every feed, including assets that are not 18 decimals.
  3. Spot prices are not used where a manipulation-resistant TWAP or a multi-source median is required.
  4. Market-hours and sequencer-downtime behaviour is defined for RWA and L2 deployments.

5. Tokens and approvals

  1. SafeERC20 or equivalent is used for every token that is not guaranteed to return a boolean.
  2. Permit paths check deadline, nonce and owner, and cannot be replayed across chains or contracts.
  3. Infinite approvals are avoided or bounded, and revoked wherever the flow allows it.
  4. Transfers to the zero address and to the contract itself are handled, not assumed away.

6. Upgradeability and storage

  1. Storage layout is append-only across upgrades, with a gap or namespaced storage.
  2. The implementation cannot be initialized or upgraded by an unauthorized caller, including through the proxy admin path.
  3. Delegatecall targets are immutable or behind a timelock, and the target is not an arbitrary user input.
  4. Upgrade tests run against the previous deployed version, not only against a fresh deploy.

7. Signatures and replay

  1. The domain separator includes chain id and verifying contract, and is recomputed after a fork.
  2. Nonces are per-signer and consumed exactly once, including on paths that revert after the check.
  3. ecrecover checks for the zero address and malleable signatures, or the code uses a vetted ECDSA library.
  4. Cross-chain messages include the source chain and a replay guard, not just a nonce.

8. Deployment and operations

  1. Constructor and initializer arguments are verified against the intended configuration before deploy.
  2. Ownership and admin roles end up with the multisig, not the deployer EOA, and the handover is tested.
  3. Source is verified on the explorer and matches the audited commit, not a later build.
  4. An incident runbook exists: who can pause, who holds keys, how users are told, and what the rollback path is.

What this checklist does not replace

A checklist is a floor, not an audit. It cannot tell you that your liquidation path is unprofitable at the edges, that two contracts disagree about who owns a share, or that a new mechanism has an attack path nobody has seen before. Those require reading the system as a whole and trying to break it.

What the list does is protect the expensive hours. A codebase that passes it lets the review start at the interesting part instead of the typos. If you want that review, see the smart contract audit, the cost guide, the DeFi audit section, or the Solana audit section.

Questions buyers ask

Is this checklist enough instead of an audit?

No. A checklist catches hygiene and known classes. An audit spends its time on the assumptions specific to your protocol: how the accounting between contracts can drift, what happens in a liquidation cascade, and which economic path nobody modelled. The checklist makes that review cheaper by removing the obvious.

What is the most common failure you see?

Access control and accounting, not exotic Solidity. A missing caller check, an admin path that skips a state update, or a rounding direction that lets a user extract value one wei at a time. Most large losses start in one of those two families.

Does the same checklist apply to Rust and Solana?

The accounting, access and oracle sections carry over. On Solana, account validation replaces part of the EVM list: owner checks, signer checks, PDA derivation and CPI trust are the equivalent of "who can call this".

Can you review the code against this list before a full audit?

That is what the first day of an audit does. If you want the hygiene work done before the paid review, run the list yourself or ask for a scoped pre-launch review.

Want the review, not just the list?

Fixed fee, 5 to 10 days, findings with proof and fix verification.

Request a quote