Before deploying a smart contract to mainnet, run through this checklist. Catching one critical issue here can save millions.
Access Control
- [ ] All privileged functions have
onlyOwner/ role-based guards - [ ]
tx.originis never used for authorization (usemsg.sender) - [ ] Initializer functions use
initializermodifier (upgradeable contracts) - [ ] Admin key is a multi-sig, not an EOA
- [ ] Ownership transfer is a two-step process
Arithmetic
- [ ] Using Solidity 0.8.x (built-in overflow checks) or
SafeMath - [ ] No division before multiplication (precision loss)
- [ ] No unchecked blocks around critical math
- [ ] Accounting for fee-on-transfer tokens where applicable
External Calls & Reentrancy
- [ ] All external calls follow Checks-Effects-Interactions (CEI)
- [ ]
ReentrancyGuardon any function that sends ETH or makes external calls - [ ] Return values from
call()/delegatecall()are checked - [ ] Cross-function and cross-contract reentrancy paths reviewed
Oracle & Price Safety
- [ ] Not using AMM spot prices for anything critical
- [ ] Using Chainlink or Uniswap TWAP for price feeds
- [ ] Staleness check on oracle answers (
updatedAttimestamp) - [ ] Fallback oracle or circuit breaker for oracle downtime
Flash Loan Vectors
- [ ] No single-block price manipulation possible
- [ ] Liquidity checks cannot be bypassed in one transaction
- [ ] Protocol-owned liquidity is not vulnerable to sandwich attacks
Upgradability
- [ ] Storage layout is documented and collision-free across proxy/impl
- [ ]
_disableInitializers()called in implementation constructor - [ ] Upgrade function is behind a timelock and multi-sig
Token Interactions
- [ ] ERC-20
transfer()/transferFrom()return values checked - [ ] Compatible with non-standard tokens (USDT, USDC with no-return)
- [ ] Deflationary / rebasing token edge cases considered
Gas & DoS
- [ ] No unbounded loops over user-controlled arrays
- [ ] No use of
block.gaslimitas a constant - [ ] Pull-over-push pattern for ETH distributions
Events & Logging
- [ ] All state-changing functions emit events
- [ ] Events include enough context to reconstruct state off-chain
Testing
- [ ] Unit tests cover happy path and edge cases
- [ ] Fuzz tests for arithmetic and state transitions
- [ ] Fork tests against mainnet state for DeFi integrations
- [ ] Code coverage > 95%
Automated Pre-Check
Many of the above items can be caught automatically. ContractScan runs static analysis and AI-assisted review on your Solidity files — no setup required.
An automated scan is not a substitute for a full professional audit, but it's an excellent first pass before you engage an audit firm.