Need Help Preparing for Your Security Audit?
Get expert guidance on smart contract security and audit preparation.
Tool Workspace
Use, understand, and apply the results
Tool Overview
Run this checklist before submitting your contracts to a security audit. Resolving these issues before the audit saves audit time and avoids findings that would otherwise delay your launch.
Key Result
A 50-point smart contract security checklist organized into 10 sections: Code Quality (10 checks — pinned Solidity, NatSpec, no unused imports), Access Control (8 checks — multisig admin, timelocks, emergency pause), Reentrancy (6 checks — nonReentrant, CEI pattern, SafeERC20), Arithmetic (5 checks — Solidity 0.8+, division safety), Oracle Security (5 checks — TWAP, staleness, divergence threshold), Flash Loan Protection (4 checks — internal accounting, same-block restrictions), Upgradeability (5 checks — proxy pattern, storage layout, initializer), Testing (7 checks — 95% coverage, fuzz tests, invariants), Deployment Readiness (5 checks), Documentation (5 checks). Score 45-50: audit-ready.
SECTION 1: CODE QUALITY (10 checks)
Solidity version is pinned (e.g., `pragma solidity 0.8.24;` not `^0.8.0`)
Named imports used (`import {ERC20} from "@openzeppelin/..."` not `import "@openzeppelin/..."`)
All functions have NatSpec documentation (`@notice`, `@param`, `@return`)
No unused imports or state variables
All state variables have explicit visibility (`public`, `private`, `internal`)
Events emitted for all state changes
Custom errors used instead of `require(bool, string)` for gas efficiency
No `tx.origin` used for authorization (use `msg.sender`)
No `block.timestamp` used for randomness (use Chainlink VRF)
No `block.number` used for time calculations (timestamps only)
SECTION 2: ACCESS CONTROL (8 checks)
All admin functions require appropriate role or ownership check
Admin key is a multisig (Gnosis Safe), not a single EOA
Ownership cannot be transferred to address(0) accidentally
Role assignments emit events
`DEFAULT_ADMIN_ROLE` is not assigned to deployer in production (use specific roles)
Time-lock on sensitive admin operations (upgrade, fee change, parameter change)
Emergency pause implemented (Pausable from OpenZeppelin)
Pause key held separately from upgrade key
SECTION 3: REENTRANCY (6 checks)
`nonReentrant` modifier on all external functions that transfer ETH or tokens
Check-Effects-Interactions pattern followed throughout
No `.call{value:}` without nonReentrant guard
No `.transfer()` or `.send()` (use `.call{value:}` with check)
Token transfers use SafeERC20 (`safeTransfer`, `safeTransferFrom`)
No external calls in constructor
SECTION 4: ARITHMETIC (5 checks)
Solidity 0.8.x used (built-in overflow protection) OR explicit SafeMath
Division before multiplication avoided (precision loss)
No division by zero possible (denominator validated)
Fixed-point arithmetic uses consistent precision (1e18 throughout)
`unchecked` blocks only used where overflow is provably impossible
SECTION 5: ORACLE SECURITY (5 checks)
No spot price used for liquidations or collateral calculation
TWAP or Chainlink price feed used for all financial calculations
Oracle staleness check implemented (reject prices older than X minutes)
Oracle manipulation protection (divergence threshold between two oracles)
Fallback oracle configured for when primary oracle fails
SECTION 6: FLASH LOAN PROTECTION (4 checks)
Internal accounting used (not `token.balanceOf(address(this))`)
Same-block action restriction where applicable
No functions that allow manipulation of stored values within one transaction
Donation attack prevention (surplus tokens don't affect accounting)
SECTION 7: UPGRADEABILITY (5 checks, if applicable)
Proxy pattern is one of: UUPS, Transparent, or Diamond (no custom pattern)
Storage layout documented and will not change in upgrades
Initializer function cannot be called twice (`initializer` modifier)
Upgrade function requires timelock + multisig
`_disableInitializers()` called in implementation constructor
SECTION 8: TESTING (7 checks)
Line coverage ≥ 95% (run `forge coverage`)
Branch coverage ≥ 88%
Fuzz tests implemented for all critical mathematical functions
Invariant tests implemented (key protocol invariants cannot be violated)
Fork tests against mainnet state for any integration with existing DeFi
All edge cases tested: zero amounts, max amounts, single user, empty state
Negative test cases: unauthorized callers, invalid inputs, over-limit values
SECTION 9: DEPLOYMENT READINESS (5 checks)
Deployment script tested on testnet (not just local)
Constructor arguments documented and validated
Contract verified on Etherscan (source code visible)
Multisig has been set up and tested before deployment
Emergency contact plan (who to call if exploit detected)
SECTION 10: DOCUMENTATION (5 checks)
README explains what the protocol does and how it works
Architecture diagram included
All external function interfaces documented
Known limitations and trust assumptions documented
Links to all deployed contract addresses
SCORING
45–50: Audit-ready. Submit to auditor.
40–44: Minor issues. Fix before submitting.
35–39: Moderate issues. Address section failures before auditing.
Below 35: Significant gaps. Audit will find many issues — resolve first to reduce cost.