Smart contract audit checklist before mainnet
Smart contract code is unforgiving. Once it’s on mainnet it’s immutable, public, and holding real value — a single bug isn’t a hotfix, it’s lost funds you can’t claw back. That’s why security can’t be a final step you bolt on before launch. Here’s the checklist we run before any contract goes to mainnet.
The mindset: audit-ready from commit one
The biggest mistake teams make is treating “the audit” as a box to tick at the end. By then, fixing a structural flaw means rewriting and re-testing under deadline pressure. Audit-ready is something you build toward from the first commit — clean architecture, full tests, and known-vulnerability checks all the way through. The external audit should confirm security, not discover that you don’t have it.
1. Comprehensive test coverage
If it isn’t tested, assume it’s broken. Before anything else:
- Unit tests for every function and branch, including failure paths.
- Fuzz testing (e.g., Foundry’s fuzzing) to throw random inputs at your invariants.
- Invariant tests — assert the properties that must always hold (total supply, balances, access rules) across any sequence of calls.
- Fork tests against real mainnet state if you integrate with other protocols.
Aim for high, meaningful coverage — not just a number, but the dangerous paths actually exercised.
2. Static analysis
Run automated analyzers (Slither and friends) on every change. They catch a surprising number of issues for free — uninitialized storage, dangerous delegatecalls, shadowed variables, and more. Wire them into CI so a regression can’t sneak in.
3. Hunt the classic vulnerabilities
Most exploits aren’t exotic — they’re the same well-known bugs. Review explicitly for:
| Vulnerability | What to check |
|---|---|
| Reentrancy | Checks-Effects-Interactions order; reentrancy guards on external calls |
| Access control | Every privileged function gated; no missing onlyOwner/role checks |
| Integer issues | Safe math / Solidity 0.8+ checks; no unchecked over/underflow |
| Oracle manipulation | No spot-price reliance; use TWAPs / robust oracles |
| Front-running / MEV | Slippage limits; commit-reveal where ordering matters |
| Unsafe external calls | Handle return values; beware untrusted contract callbacks |
| DoS | No unbounded loops; gas-griefing resistance |
4. Gas optimization (it’s also a security issue)
Gas isn’t only about cost. Unbounded loops and expensive operations can be turned into denial-of-service vectors — an attacker makes a function too expensive to ever execute. Optimize storage layout, cap iterations, and pull patterns over push where it matters.
5. Independent / external audit
A fresh, expert set of eyes finds what the authors can’t see — you’re too close to your own code. Engage a reputable third-party auditor, give them clean code, full tests, and documentation, and fix every finding (or document why a finding is a non-issue). Re-audit after significant changes. This is the step you don’t skip when real value is at stake.
A clean external audit doesn’t prove there are no bugs — it sharply reduces the odds. Treat it as risk reduction, not a guarantee, and design so a single failure can’t drain everything.
6. Safe deployment to mainnet
The code can be perfect and the deployment still sink you. Before and during launch:
- Testnet dry-run of the exact deployment scripts and post-deploy configuration.
- Verify the source on the block explorer so it’s publicly auditable.
- Lock down ownership — multisig, and timelocks on privileged actions.
- Plan upgradeability deliberately — if you use proxies, understand the risks; if you don’t, you can’t patch, so be sure.
- Have a pause / circuit breaker for emergencies where appropriate.
After mainnet: it’s not over
- Monitoring & alerting on contract events and anomalies.
- A bug bounty (e.g., Immunefi) to reward responsible disclosure.
- An incident response plan — who does what, and how fast, if something’s wrong.
How we approach it
At Malgary Labs we write contracts to be audit-ready from day one — comprehensive tests, static analysis in CI, gas optimization, and known-vulnerability checks built in, not bolted on. We prepare the codebase for external audit and coordinate with third-party auditors before mainnet. We’ve shipped production on-chain systems on Solana (Anchor/Rust) and EVM chains — see AVRIO, a scan-to-earn network handling thousands of transactions a minute.
Shipping a contract that holds real value? Get the security right before mainnet, not after an incident — see smart contract development or book a free call.