Writing Secure Smart Contracts: Common Pitfalls & How to Avoid Them
Why Smart Contract Security Matters
Smart contracts are immutable and operate with real money. A tiny bug can lead to catastrophic losses (see: The DAO, Poly Network). As a developer, security needs to be part of your design from day one.
Top 5 Smart Contract Vulnerabilities
1. Reentrancy
This infamous vulnerability lets attackers drain funds by recursively calling vulnerable functions.
solidity// ❌ Vulnerable versionfunction withdraw() public {uint amount = balances[msg.sender];(bool success, ) = msg.sender.call{value: amount}("");require(success);balances[msg.sender] = 0;}// ✅ Safe versionfunction withdraw() public {uint amount = balances[msg.sender];balances[msg.sender] = 0;(bool success, ) = msg.sender.call{value: amount}("");require(success);}
2. Integer Overflows/Underflows
Before Solidity 0.8, math operations didn’t check for overflow.
solidity// ✅ Use SafeMath (before 0.8)using SafeMath for uint256;uint256 newBalance = balance.add(100);
3. Front-running
Avoid exposing parameters that can be manipulated before execution.
4. Uninitialized Storage Pointers
solidity// ❌ This creates storage collisionscontract Test {struct Data {uint x;}Data public data;function write() public {Data storage d;d.x = 1; // writes to slot 0}}
Use Tools Like:
- Slither: Static analysis
- MythX: Security analysis as a service
- OpenZeppelin Defender: Secure operations dashboard
Real-World Example
Here’s an example image from a reentrancy attack visualization:
Reentrancy Attack Flow
Summary
Vulnerability | Description | Mitigation |
---|---|---|
Reentrancy | Recursive call manipulation | Checks-Effects-Interactions |
Overflow | Math wraparound | SafeMath / Solidity >= 0.8 |
Front-running | Parameter manipulation | Commit-reveal / Delay |
Final Advice
Audit early, audit often. Treat smart contracts like launching a space shuttle: test rigorously, simulate all edge cases, and assume nothing.