Smart Contract Security Checklist
Download Security Checklist
Get the printable version of this comprehensive security checklist for your audit process.
Smart contract security is non-negotiable. A single vulnerability can result in millions of dollars in losses and irreparable damage to your project's reputation. This comprehensive checklist covers essential security considerations across the entire smart contract development lifecycle, from design to deployment and beyond.
CRITICAL REMINDER
This checklist is a guide, not a substitute for professional security audits. Always engage reputable auditing firms before deploying contracts that handle real value.
Table of Contents
1. Secure Design Principles
Security starts at the design phase. Apply these fundamental principles before writing any code.
Core Principles
Principle of Least Privilege
Grant minimum necessary permissions. No address should have more authority than required for its function.
Defense in Depth
Layer multiple security measures. Don't rely on a single check or mechanism.
Fail Securely
When errors occur, fail in a way that maintains security. Use require() statements liberally.
Keep It Simple
Complexity is the enemy of security. Simpler code is easier to audit and less prone to bugs.
Checks-Effects-Interactions Pattern
Always: 1) Check conditions, 2) Update state, 3) Make external calls. Prevents reentrancy.
Trust Minimization
Minimize trust assumptions. Verify everything, trust nothing from external sources.
Design Checklist
Document all assumptions and invariants
What should always be true? What conditions must hold?
Define clear access control model
Who can call what? Use role-based access control (RBAC) when appropriate.
Plan for upgradeability (if needed)
Proxy patterns vs. immutability? Consider security trade-offs carefully.
Design emergency stop mechanisms
Pause functionality for critical functions. Plan how to handle paused state.
Consider rate limiting and caps
Limit damage from exploits with withdrawal limits, time delays, or caps.
Plan for oracle failures
What happens if price feeds fail or become stale? Have fallback mechanisms.
2. Common Vulnerabilities (Top 20)
Check your contracts for these well-known vulnerability patterns. Each has led to major exploits.
1. Reentrancy
CRITICALExternal calls that allow attackers to re-enter your contract before state updates complete.
Use Checks-Effects-Interactions pattern
Implement ReentrancyGuard from OpenZeppelin
Update state before external calls
2. Integer Overflow/Underflow
CRITICALArithmetic operations that wrap around due to exceeding type limits.
Use Solidity 0.8+ (built-in overflow checks)
For older versions, use SafeMath library
Be careful with unchecked blocks in 0.8+
3. Access Control Issues
CRITICALMissing or incorrect permission checks allowing unauthorized access.
Use OpenZeppelin's Ownable or AccessControl
Explicitly check msg.sender for privileged functions
Never rely on tx.origin for authentication
4. Front-Running / MEV
HIGHAttackers observing pending transactions and placing their own ahead.
Implement commit-reveal schemes for sensitive operations
Add slippage protection for DEX interactions
Consider batch auctions or private mempools
5. Unchecked External Call Returns
CRITICALIgnoring return values from external calls that may fail silently.
Always check return values of external calls
Use SafeERC20 for token transfers
Handle failed transfers gracefully
6. Denial of Service (DoS)
HIGHConditions that can halt contract operation or make functions unusable.
Avoid loops with unbounded iterations
Use pull over push for payments
Don't rely on external calls succeeding
7. Timestamp Dependence
MEDIUMRelying on block.timestamp which miners can manipulate (~15 seconds).
Don't use timestamps for critical randomness
Allow ~15 second tolerance in time checks
Use block numbers for ordering if possible
8. Delegatecall to Untrusted Contract
CRITICALDelegatecall executes external code in your contract's context.
Only delegatecall to trusted, audited contracts
Understand storage layout conflicts in proxies
Never allow user-controlled delegatecall targets
9. Short Address Attack
MEDIUMExploiting improper input validation to manipulate transfer amounts.
Validate msg.data.length in functions
Check address parameters are 20 bytes
10. Oracle Manipulation
CRITICALPrice oracles manipulated through flash loans or low liquidity.
Use time-weighted average prices (TWAP)
Implement multiple oracle sources
Never use spot prices for critical decisions
CONTINUE READING
These are 10 of the 20 most common vulnerabilities. Download the full checklist for vulnerabilities 11-20, including flash loan attacks, storage collisions, signature replay, and more.
3. Development Best Practices
Follow these practices during development to minimize vulnerabilities.
Code Quality
Use latest stable Solidity version
Stay current with security patches and improvements
Use OpenZeppelin contracts as foundation
Battle-tested implementations of common patterns
Follow style guide and naming conventions
Consistent code is easier to review and audit
Write comprehensive NatSpec comments
Document function behavior, parameters, and security considerations
Avoid assembly unless absolutely necessary
Assembly bypasses safety checks and is error-prone
Minimize contract size
Stay under 24KB limit, use libraries for shared code
Use explicit function visibility
Always specify public, private, internal, or external
Emit events for all state changes
Critical for monitoring and debugging
Gas Optimization vs Security
WARNING
Never sacrifice security for gas optimization. Write secure code first, optimize later if needed. Many exploits happen because developers removed safety checks to save gas.
4. Testing & Verification
Comprehensive testing is essential for identifying vulnerabilities before deployment.
Test Coverage Requirements
Unit tests for all functions
Test normal operation and edge cases
Integration tests for contract interactions
Test how contracts work together
Negative tests for failure conditions
Verify requires/reverts work correctly
Fuzz testing with random inputs
Use Foundry's fuzzer or Echidna
Formal verification for critical functions
Mathematically prove correctness
Achieve 100% branch coverage
Every code path should be tested
Test on fork of mainnet
Verify interactions with real contracts
Invariant testing
Verify properties that should always hold true
5. Audit Preparation
Prepare thoroughly before engaging an audit firm to maximize the value of the audit.
Freeze code before audit
No changes during audit period
Provide comprehensive documentation
Architecture diagrams, spec docs, known issues
Run static analysis tools first
Fix obvious issues before paying for audit
Document all assumptions
What should auditors verify?
Choose reputable audit firm
Trail of Bits, OpenZeppelin, CertiK, Quantstamp, etc.
Address all findings
Fix or document why not fixed
Consider multiple audits
Different firms find different issues
6. Deployment Security
Deployment is a critical phase where mistakes can be costly.
Deploy to testnet first
Verify everything works as expected
Use hardware wallet for deployment
Never use hot wallet with deployment keys
Verify constructor parameters
Triple-check addresses and values
Verify contract source on Etherscan
Transparency and verification
Transfer ownership to multi-sig
Never use EOA as owner in production
Document all contract addresses
Maintain official registry
Set up monitoring before launch
Be ready to detect issues immediately
7. Post-Deployment Monitoring
Continuous monitoring is essential for detecting and responding to security issues.
Monitor all transactions in real-time
Use Tenderly, Forta, or custom monitoring
Set up alerts for unusual activity
Large transfers, failed transactions, etc.
Track contract balance changes
Unexpected drains are red flags
Monitor oracle feeds
Verify price data stays reasonable
Run bug bounty program
Incentivize white-hat discovery
Maintain incident response team
Be ready to act 24/7
8. Incident Response Plan
Have a clear plan for responding to security incidents.
Incident Response Steps
- Detection: Identify the incident through monitoring or reports
- Assessment: Determine severity and impact
- Containment: Pause affected contracts if possible
- Communication: Notify users and stakeholders
- Investigation: Determine root cause
- Recovery: Fix and redeploy if needed
- Post-Mortem: Document and learn
Maintain emergency contacts list
Team, auditors, white-hats, exchange contacts
Have multi-sig ready to pause
Practice emergency procedures
Prepare communication templates
Pre-draft incident announcements
Know how to contact exchanges
May need to pause trading quickly
9. Security Tools & Resources
Essential tools for smart contract security.
Static Analysis
Slither
Fast static analyzer from Trail of Bits
Mythril
Security analysis tool using symbolic execution
Semgrep
Pattern-based code analysis
Aderyn
Rust-based Solidity static analyzer
Testing & Fuzzing
Foundry
Fast testing framework with built-in fuzzing
Echidna
Property-based fuzzer for Ethereum
Medusa
Cross-chain smart contract fuzzer
Hardhat
Development environment with testing suite
Monitoring
Tenderly
Real-time monitoring and debugging platform
Forta
Decentralized security monitoring network
OpenZeppelin Defender
Security operations platform
Blocknative
Mempool monitoring and gas optimization
Conclusion
Smart contract security is an ongoing process, not a one-time event. The landscape constantly evolves with new attack vectors and defense mechanisms. Stay informed, follow best practices, and never cut corners on security.
Remember: The cost of a security audit is nothing compared to the cost of an exploit. Invest in security early and thoroughly—your users and your project depend on it.
Need Professional Security Audit?
Symmetrium Tech partners with leading security audit firms and provides comprehensive security assessment services. We help you identify vulnerabilities before deployment and implement security best practices throughout your development process.
Request Security Consultation