EducationalAdvanced

Smart contract audit checklist: pre-audit prep to post-deploy

A practical smart contract audit checklist: scoping, threat model, access control, oracles, signatures, EIP-7702, testing, tools and deployment ops.

Blockchain Army cover graphic reading 'Smart contract audit checklist'
10minread · 2,196 words
8sections
14sources cited
Advancedreading level

A smart contract audit is only as good as what you hand the auditors and what you do after they leave. Use this checklist in three passes. Before the audit, freeze the scope, write the specs and threat model, and get your own tests and tools clean. During the audit, make sure every risk class below is covered. After it, ship the exact audited code behind a multisig and timelock, then keep monitoring. Each item maps to public references: the OWASP Smart Contract Top 10 (2026 edition), the Solidity documentation, ConsenSys Diligence and Trail of Bits guidance, and the relevant EIPs.

This is a working list for teams on EVM chains. It does not replace an auditor; it makes the auditor's time count.

Flow diagram of where an audit sits in the release cycle: freeze scope, internal review, external audit, fix and re-review, deploy behind multisig and timelock, then monitor and run a bug bounty
An audit is one step in a release cycle, not the whole of it. Source: Blockchain Army; based on OWASP SCSVS, Trail of Bits Building Secure Contracts and ConsenSys Diligence best practices.

Which references to use in 2026

Two references many teams still cite have moved on.

Reference Status (as of October 2026) Use it for
OWASP Smart Contract Top 10 2026 edition, based on 2025 incident and survey data Prioritising risk classes
SWC Registry Marked "no longer actively maintained"; not thoroughly updated since 2020 Historical weakness IDs only
EEA EthTrust Security Levels Recommended by the SWC Registry as the current guidance for reviewers Detailed requirements for reviewers
OWASP SCSVS Maintained verification standard Developer-side requirements
Solidity docs, "Security considerations" Updated with the compiler Language-level pitfalls
ConsenSys Diligence best practices; Trail of Bits Building Secure Contracts Maintained guides Patterns, tooling walkthroughs

The OWASP 2026 list ranks the categories as follows:

Rank Category
SC01 Access control vulnerabilities
SC02 Business logic vulnerabilities
SC03 Price oracle manipulation
SC04 Flash loan-facilitated attacks
SC05 Lack of input validation
SC06 Unchecked external calls
SC07 Arithmetic errors (rounding and precision)
SC08 Reentrancy attacks
SC09 Integer overflow and underflow
SC10 Proxy and upgradeability vulnerabilities

Access control and business logic top the list. That matches the incident record: many losses come from who can call what, and from logic that does what the code says but not what the designers meant. Classic reentrancy still matters, but it is no longer the headline risk.

Pass 1: before the audit

Auditors are expensive per hour. Every hour they spend working out what your code is supposed to do is an hour not spent breaking it.

Scoping and documentation

  • Freeze a commit hash. The audit covers that commit and nothing else. Code changed after the freeze needs its own review.
  • List in-scope files with line counts, and out-of-scope dependencies with their versions.
  • Write a specification. For each external function: who may call it, what it changes, and what must always hold before and after. Plain English is fine.
  • Document roles and privileges. Every admin, owner, keeper, pauser and upgrader: what they can do and which key or multisig holds the role.
  • List external dependencies. Oracles, bridges, DEX pools, token standards you integrate with, and what you assume about each.
  • List known issues and accepted risks, so auditors do not spend time rediscovering them.
  • Give deployment details: target chains, constructor arguments, initialisation order, upgrade plan.

Threat model

Write down, for your protocol specifically:

  • Assets at risk. User deposits, protocol fees, governance power, minting rights.
  • Actors. Ordinary users, privileged roles, liquidators, MEV searchers, a malicious token contract, a compromised admin key, a manipulated oracle.
  • Trust boundaries. Where your code calls code you do not control, and where off-chain systems (keepers, relayers, front ends) can influence on-chain state.
  • Worst cases. "What is the most an attacker can take in one block?" and "What happens if the admin key is stolen?"

A threat model also helps scope operational risk. As the Bitget breach in September showed, attackers often go after the systems that tell signers what to sign, not the contracts themselves.

Internal readiness

  • Compiles cleanly with a pinned compiler version and no unexplained warnings. The Solidity docs advise: "Take warnings seriously."
  • Unit tests pass and coverage reports are included, with gaps explained.
  • Slither and Aderyn output triaged: fixed or annotated as false positives.
  • Fuzz and invariant suites run, with the invariants documented.
  • NatSpec comments on public and external functions.
  • Dead code, debugging statements and unused imports removed.

Pass 2: the risk checklist

This is the core of the review. Use it to check auditor coverage and to self-review before you hand over the code.

Access control (SC01)

  • Every state-changing function has an explicit access decision, including "anyone may call this, and that is safe".
  • Initialisers can be called only once and cannot be front-run after deployment.
  • Role admin relationships are correct: who can grant, revoke and renounce each role.
  • Two-step ownership transfer is used where losing ownership would be fatal.
  • No authorisation via tx.origin. The Solidity docs are blunt: "Never use tx.origin for authorization."

Upgradeability (SC10)

  • Storage layout is compatible between versions. Use namespaced storage (ERC-7201) or documented gaps.
  • Implementation contracts cannot be initialised or self-destructed by an attacker.
  • The upgrade function is protected by a multisig and, ideally, a timelock.
  • The upgrade path has been tested with a fork test: deploy v1, populate state, upgrade, check state.

Oracles and price manipulation (SC03, SC04)

  • No prices read from a single DEX pool's spot reserves. These can be moved within one transaction using a flash loan.
  • External feeds are checked for staleness, zero or negative values, and decimals.
  • There is a defined behaviour when the oracle fails: pause, fall back or revert, never silently use bad data.
  • Any function whose outcome depends on a price has been tested against a manipulated price within a single transaction.

Reentrancy and external calls (SC06, SC08)

  • Checks-effects-interactions: the Solidity docs say "interaction with other contracts should be the very last step in any function".
  • Reentrancy guards on functions that make external calls and touch shared state, including cross-function and read-only reentrancy via view functions other protocols consume.
  • Return values of low-level calls are checked.
  • Token hooks (ERC-777, ERC-721 and ERC-1155 receivers) are treated as external calls.

Arithmetic and rounding (SC07, SC09)

  • Solidity 0.8+ checked arithmetic is on; every unchecked block is justified.
  • Rounding direction always favours the protocol: round down what users receive, round up what they owe.
  • Multiply before divide; precision loss is tested at small and large values.
  • First-depositor and "donation" attacks on share-based vaults are considered: can someone inflate the share price to round later depositors to zero?

Signatures and replay

  • Typed signatures follow EIP-712, with a domain separator that includes chainId and verifyingContract.
  • The domain separator is recomputed if the chain ID changes (fork safety).
  • Every signed message has a nonce or is otherwise single-use, plus a deadline.
  • ecrecover returning address(0) is rejected, and signature malleability is handled. Use a maintained library rather than raw ecrecover.
  • Permit (EIP-2612) flows tolerate a front-run permit, so a griefed permit call does not block the user.

EIP-7702 and caller assumptions

EIP-7702, live on Ethereum mainnet since the Pectra upgrade in May 2025, lets an externally owned account delegate to contract code. The specification notes that it "breaks the invariant that msg.sender == tx.origin only happens in the topmost execution frame". Check:

  • No logic uses msg.sender == tx.origin as a guard against contracts, flash loans or reentrancy.
  • No logic assumes an address with no code today will never have code. extcodesize == 0 is not proof of an EOA.
  • If you build a delegate contract for 7702 wallets: initialisation must be signed by the account's key, storage must avoid collisions (the EIP suggests ERC-7201), and calls must carry replay protection.

MEV and front-running

  • Swaps and liquidity actions take user-supplied minimum outputs and deadlines.
  • Commit-reveal or batch designs are used where ordering would leak value (auctions, mints, liquidations).
  • Ask: if a searcher sees this transaction in the mempool, what can they gain by inserting transactions before or after it? Our explainer on MEV bots covers the mechanics.

Token-specific behaviour

Token behaviour What to check
Fee-on-transfer Measure balance before and after transfer instead of trusting the amount argument
Rebasing Do not cache balances; use shares internally if you must hold rebasing tokens
Missing return value (e.g. older USDT) Use a safe-transfer wrapper
Non-18 decimals Normalise decimals; test with 6 and 8
Blocklists or pausable tokens Plan for transfers to or from the protocol reverting
Upgradeable tokens Behaviour can change after your audit; document the dependency

If your protocol accepts arbitrary tokens, assume all of the above at once.

Business logic (SC02)

No tool finds these reliably. Walk through each user flow against the specification, then try to break the economics: can a user gain by doing things in an unexpected order, in the same block, with a flash loan, or by being both sides of a trade? Write the invariants down ("total shares × price per share = total assets", "no user can withdraw more than they deposited plus yield") and test them.

Testing and tools

Layer What it catches Tools
Unit tests Expected behaviour, access control, reverts Foundry, Hardhat
Fuzz tests Edge values in single functions Foundry fuzzing, Echidna, Medusa
Invariant / stateful fuzzing Broken system properties across call sequences Foundry invariant tests, Echidna, Medusa
Fork tests Real integrations: oracles, pools, tokens as deployed Foundry fork mode
Static analysis Known bug patterns, dangerous constructs Slither (Trail of Bits), Aderyn (Cyfrin)
Manual review Business logic, economic attacks, design flaws Auditors, internal peer review

Slither and Aderyn are fast and cheap, so run them in CI on every pull request. Echidna is Trail of Bits' property-based fuzzer. Medusa is a go-ethereum-based fuzzer from the same Crytic organisation, inspired by Echidna. Foundry covers unit, fuzz, invariant and fork testing in one toolchain. Trail of Bits' Building Secure Contracts repository has walkthroughs for most of these.

Treat tool output as input to review, not as a verdict. A clean Slither run means none of its detectors fired, not that the code is safe.

Pass 3: deployment and operations

Several of the largest losses of 2026, including Bitget's, came from keys, signers or infrastructure rather than a contract bug. Your audit report does not cover any of this unless you asked for it.

Area Checklist
Deployment Deploy the exact audited commit; verify source on the block explorer; script deployment and record addresses; check constructor and initialiser arguments on-chain
Admin keys Privileged roles held by a multisig with independent signers on separate devices; no single EOA admin
Timelocks Upgrades and parameter changes go through a timelock users can see; emergency pause is the only fast path, and pausing cannot move funds
Signing hygiene Signers verify decoded transaction data on hardware devices, not just a hash shown by a web interface
Monitoring Alerts on admin calls, large outflows, oracle deviations, paused state, unexpected upgrades
Incident response Written runbook: who can pause, who contacts exchanges and stablecoin issuers, who speaks publicly; rehearsed at least once
Bug bounty Public program with clear scope and payout, live from launch day
Re-audit triggers Any change to in-scope code, new integrations, or new chains

How to read the audit report

  • Every finding should have a status: fixed (with commit), acknowledged (with reason) or disputed (with reasoning).
  • Check that the fix review covers the final commit you deploy, not an intermediate one.
  • Severity is the auditor's judgment. A "low" that touches an admin path may matter more to you than it looks.
  • Publish the report. Users and partners increasingly expect it, and our audit review explainer covers what a good one contains.

For a broader introduction see our guides on conducting a smart contract security audit and the most common smart contract vulnerabilities. If you want a second pair of eyes before or after an external audit, that is the scope of our audit review service.

FAQ

How long before launch should we book an audit?

Book as early as you can freeze the code, and leave time after the audit for fixes and a re-review. Audit firms' calendars can fill up well in advance. Do not plan a launch date that assumes zero findings.

Is one audit enough?

For simple, non-upgradeable contracts it may be. For protocols holding significant value, many teams combine a firm audit with a public contest or a second firm, then a bug bounty after launch. Any change to audited code needs its own review.

Does a clean Slither or Aderyn run mean the code is safe?

No. Static analysers detect known patterns. They do not understand your business logic or economics, which is where the top OWASP 2026 categories sit. Use them to clear the obvious issues before human review.

Is the SWC Registry still useful?

Its weakness IDs are still widely referenced, but the registry itself says it is no longer actively maintained and has not been thoroughly updated since 2020. It points reviewers to the EEA EthTrust Security Levels specification and developers to OWASP SCSVS.

What does EIP-7702 change for existing contracts?

Externally owned accounts can now run delegated code. Any check that relies on msg.sender == tx.origin, or on an address having no code, to mean "this is a plain user wallet" is no longer reliable. Review those checks and replace them with explicit access control and reentrancy guards.

What should we have ready on day one of the audit?

A frozen commit hash, a specification, a role and privilege map, a threat model, a known-issues list, passing tests with coverage, triaged static analysis output, and a named engineer who can answer auditors' questions the same day.

Sources

  1. OWASP Smart Contract Security Project — Smart Contract Top 10: 2026
  2. OWASP — Smart Contract Security Verification Standard (SCSVS)
  3. SWC Registry — Smart Contract Weakness Classification (maintenance notice)
  4. Enterprise Ethereum Alliance — EthTrust Security Levels specification
  5. Solidity documentation — Security considerations
  6. ConsenSys Diligence — Smart contract security best practices
  7. Trail of Bits — Building Secure Contracts
  8. Ethereum Improvement Proposals — EIP-712: Typed structured data hashing and signing
  9. Ethereum Improvement Proposals — EIP-7702: Set Code for EOAs
  10. Trail of Bits — Slither
  11. Cyfrin — Aderyn
  12. Trail of Bits — Echidna
  13. Crytic — Medusa
  14. Foundry — Documentation

How we research, write and fact-check: Editorial & AI policy.

Disclaimer: this article is for informational and educational purposes only and does not constitute financial, investment, legal or tax advice. Crypto-assets are volatile and high-risk: always do your own research (DYOR) and consult a qualified professional before making any decision. Not financial advice.

Work with us

Building in this space? Let's talk.

See our Audit Review service, or book a call with the team.

Stay up to date with crypto!

Join our free newsletter for weekly crypto updates

Subscribe

Free daily alpha for you

telegram community with daily insights, curiosities, news and alpha from the blockchain world.

Free to join for a limited period of time.

Your blockchain digest of choice, directly in your inbox