目录
Blockchain Smart Contract Security¶
Common Vulnerabilities¶
1. Reentrancy¶
The most famous vulnerability (DAO hack).
// VULNERABLE
function withdraw() public {
uint amount = balances[msg.sender];
(bool success, ) = msg.sender.call{value: amount}("");
require(success);
balances[msg.sender] = 0; // Too late!
}
// SAFE: Checks-Effects-Interactions pattern
function withdraw() public {
uint amount = balances[msg.sender];
balances[msg.sender] = 0; // Update first
(bool success, ) = msg.sender.call{value: amount}("");
require(success);
}
2. Integer Overflow/Underflow¶
// Solidity 0.8+ has built-in checks
// For older versions, use SafeMath
// VULNERABLE (pre-0.8)
function transfer(uint amount) public {
balances[msg.sender] -= amount; // Can underflow!
}
3. Access Control¶
// VULNERABLE
function setOwner(address newOwner) public {
owner = newOwner; // Anyone can call!
}
// SAFE
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
function setOwner(address newOwner) public onlyOwner {
owner = newOwner;
}
4. Front-Running¶
// VULNERABLE: Price can be front-run
function buyToken() public payable {
uint amount = msg.value * price;
token.transfer(msg.sender, amount);
}
// SAFE: Commit-reveal scheme
function commitBuy(bytes32 commitment) public {
commitments[msg.sender] = commitment;
}
function revealBuy(uint amount, bytes32 secret) public {
require(keccak256(abi.encode(amount, secret)) == commitments[msg.sender]);
// Process buy
}
Best Practices¶
1. Use OpenZeppelin¶
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract MyContract is Ownable, ReentrancyGuard {
function withdraw() public nonReentrant {
// Safe from reentrancy
}
}
2. Gas Optimization¶
// Bad: Multiple storage reads
function sum() public view returns (uint) {
return values[0] + values[1] + values[2];
}
// Good: Cache in memory
function sum() public view returns (uint) {
uint[3] memory v = values;
return v[0] + v[1] + v[2];
}
3. Event Logging¶
event Transfer(address indexed from, address indexed to, uint amount);
function transfer(address to, uint amount) public {
// ... logic
emit Transfer(msg.sender, to, amount);
}
Security Checklist¶
- [ ] Reentrancy guards on external calls
- [ ] Integer overflow checks (or Solidity 0.8+)
- [ ] Access control on sensitive functions
- [ ] Input validation
- [ ] Event emission for state changes
- [ ] Gas limit considerations
- [ ] External contract interaction safety
- [ ] Upgrade mechanism security (if applicable)
Testing Tools¶
| Tool | Purpose |
|---|---|
| Slither | Static analysis |
| Mythril | Symbolic execution |
| Echidna | Fuzzing |
| Hardhat | Testing framework |