Skip to content
FinGuard

Security Guide

Web3 Security Checklist: 15 Steps to Protect Your Smart Contract

A comprehensive, actionable checklist covering everything from access control to monitoring — designed to catch vulnerabilities before attackers do.

Pre-Deployment Security Checklist

Complete these 15 checks before deploying any smart contract to mainnet.

01

Implement Role-Based Access Control

Use OpenZeppelin's AccessControl or Ownable2Step instead of raw address checks. Define separate roles for admin, operator, and pauser functions. Never use tx.origin for authorization.

02

Guard Against Reentrancy

Apply the checks-effects-interactions pattern to all external calls. Use ReentrancyGuard for functions that transfer ETH or interact with untrusted contracts. Test with deliberately malicious callback contracts.

03

Validate All External Inputs

Check for zero addresses, overflow values, empty arrays, and out-of-range parameters at function entry points. Never trust that callers will provide sensible inputs — enforce constraints on-chain.

04

Handle Integer Arithmetic Safely

Solidity 0.8+ has built-in overflow checks, but unchecked blocks bypass them. Audit every unchecked block for overflow/underflow risk. Watch for division by zero and precision loss in fixed-point math.

05

Secure Oracle Dependencies

Use time-weighted average prices (TWAP) or multiple oracle sources to resist flash loan manipulation. Add staleness checks, minimum response thresholds, and fallback logic for oracle failures.

06

Lock and Verify Compiler Version

Pin the Solidity version with a specific pragma (e.g., 0.8.20) rather than using floating pragmas (^0.8.0). Ensure all contracts in the project compile with the same version to avoid subtle behavioral differences.

07

Minimize Upgrade Surface Area

If using upgradeable proxies, restrict upgrade authority with timelocks and multisig governance. Prevent storage layout collisions. Consider whether upgradeability is truly needed — immutable contracts are simpler to reason about.

08

Implement Emergency Stop Mechanisms

Add pausable functionality for critical operations. Design the pause mechanism so it can't be abused for censorship but can halt operations during active exploits. Test that pause actually blocks all critical paths.

09

Protect Against Front-Running

Use commit-reveal schemes, private mempools (Flashbots Protect), or deadlines for time-sensitive operations. Minimize the extractable value in pending transactions.

10

Audit Token Approval Patterns

Avoid infinite approvals where possible. Implement EIP-2612 permit for gasless approvals. Check for approval race conditions and ensure that decreaseAllowance is used rather than approve(0) followed by approve(newAmount).

11

Test with Realistic Fork Simulations

Run integration tests against mainnet forks to catch issues with real token balances, pool states, and oracle values. Hardhat and Foundry both support forked testing — use it to simulate real deployment conditions.

12

Review Gas Optimization vs. Safety Trade-offs

Gas-optimized code can introduce subtle security issues. Never skip safety checks to save gas. Document any unchecked blocks or assembly usage with explicit safety justifications.

13

Verify Contract Source on Block Explorer

Publish and verify source code on Etherscan or the relevant block explorer immediately after deployment. This enables public scrutiny and builds trust. Ensure the verified source exactly matches the deployed bytecode.

14

Set Up Monitoring and Alerting

Deploy on-chain monitoring before launch, not after. Watch for unusual transfer patterns, privilege escalation, governance proposals, and parameter changes. Tools like FinGuard's 24/7 monitoring layer catch active exploits in real time.

15

Get an Independent Security Audit

Internal review is necessary but not sufficient. Hire an independent auditor who will attempt to exploit your contract in a sandbox environment. Require exploit evidence for findings, not just theoretical risk lists.

Common Vulnerabilities to Watch For

These vulnerability classes account for the majority of DeFi exploits in 2024-2025.

Reentrancy Attacks

The most classic smart contract vulnerability. Attackers re-enter a function before the first call completes, draining funds through recursive calls. The DAO hack in 2016 lost $60M to this pattern.

Oracle Manipulation

Attackers use flash loans to temporarily manipulate on-chain price feeds, then exploit protocols that rely on spot prices. This has been the leading exploit vector in DeFi since 2020.

Access Control Flaws

Missing or incorrect permission checks on privileged functions — allowing anyone to call admin operations, update parameters, or drain funds. Often caused by incomplete modifier coverage.

Flash Loan Exploits

Atomically borrowing large amounts to manipulate governance votes, pool ratios, or pricing mechanisms within a single transaction. Defense requires time-weighted values and multi-block confirmation.

Logic Bugs in Business Rules

Incorrect implementation of lending rates, reward calculations, or liquidation thresholds. These bugs are specific to each protocol and are why automated tools alone are insufficient — human reasoning catches design flaws.

Testing Requirements

The minimum testing standard before any smart contract goes to mainnet.

Unit Tests (90%+ Coverage)

Every public and external function should have positive and negative test cases. Target at least 90% branch coverage. Use Foundry's forge coverage or Hardhat coverage plugins to measure.

Integration Tests on Mainnet Forks

Test the full deployment flow on a forked mainnet state. Verify that interactions with DEX pools, lending protocols, and oracles behave as expected with real on-chain data.

Fuzz Testing with Property Invariants

Define invariants (e.g., total supply never exceeds cap, user balance never goes negative) and let a fuzzer generate thousands of random inputs. Foundry and Echidna are leading tools for this.

Formal Verification for Critical Paths

For high-value contracts managing significant TVL, use formal verification tools (Certora, Solidity SMTChecker) to mathematically prove that critical properties hold under all possible inputs.

Frequently Asked Questions

How long does it take to complete this checklist?

For a well-structured project with existing test coverage, expect 2-5 days to systematically work through all 15 items. For projects starting from scratch, budget 1-2 weeks for implementing proper access control, testing infrastructure, and monitoring setup.

Can automated tools replace a manual security review?

Automated tools (static analyzers, fuzzers, formal verification) catch known vulnerability patterns efficiently but miss business logic flaws, economic design issues, and novel attack vectors. The best approach combines automated tools for broad coverage with expert review for depth — which is exactly how FinGuard's 7-layer pipeline works.

What's the most important single item on this checklist?

If you can only do one thing, get an independent security audit (#15). An experienced auditor will catch most of the other items during their review. But relying solely on an audit without implementing the other items means you're creating unnecessary work and risk.

Should I do this checklist before or after an audit?

Before. Completing this checklist means your auditor spends time finding deep, non-obvious issues instead of flagging basic hygiene problems. This gives you more value per dollar spent on the audit. Think of it like cleaning your house before the inspector arrives.

Ready for a professional audit?

Complete your checklist, then let FinGuard's 7-layer AI engine verify your work with real sandbox exploits.