DeFi Protocol Security and Reliability
Building and evaluating secure DeFi protocols. Common vulnerabilities, defense patterns, and security best practices.
🎯 What You'll Learn
- Identify common DeFi vulnerabilities
- Understand attack patterns and exploits
- Evaluate protocol security posture
- Apply security best practices
The $10 Billion Problem
Over $10 billion has been stolen from DeFi protocols. The attacks are:
- Repeatable (same patterns)
- Preventable (known mitigations)
- Devastating (total fund loss)
Understanding security isn’t optional-it’s survival.
What You’ll Learn
By the end of this lesson, you’ll understand:
- Common vulnerabilities - Reentrancy, oracle manipulation, access control
- Attack anatomy - How exploits unfold
- Defense patterns - What secure protocols do differently
- Security evaluation - How to assess protocols
The Foundation: Top Vulnerability Classes
| Vulnerability | Lost (2022) | Prevention |
|---|---|---|
| Access Control | $600M+ | Proper modifiers, multi-sig |
| Oracle Manipulation | $500M+ | TWAP, multiple sources |
| Reentrancy | $300M+ | Checks-Effects-Interactions |
| Logic Errors | $400M+ | Formal verification, testing |
The “Aha!” Moment
Here’s what separates exploited protocols from secure ones:
Most exploits aren’t clever-they’re obvious in hindsight. Missing access control on admin functions. Single-block oracle prices. Unchecked return values. The patterns are known, but teams skip security under time pressure. Every major exploit could have been prevented by following known best practices.
Security is a process, not a feature.
Vulnerability Deep Dive
1. Reentrancy
The attacker calls back into the vulnerable function before state updates:
// VULNERABLE
function withdraw() external {
uint256 balance = balances[msg.sender];
(bool success,) = msg.sender.call{value: balance}(""); // External call
require(success);
balances[msg.sender] = 0; // State updated AFTER call
}
// Attack: Attacker's receive() calls withdraw() again
// Result: Multiple withdrawals before balance set to 0
Fix: Checks-Effects-Interactions
function withdraw() external {
uint256 balance = balances[msg.sender];
balances[msg.sender] = 0; // Update state FIRST
(bool success,) = msg.sender.call{value: balance}("");
require(success);
}
2. Oracle Manipulation
Spot price can be manipulated within a single transaction:
// VULNERABLE: Uses spot price
uint256 price = pool.getReserves().token0 / pool.getReserves().token1;
// Attack:
// 1. Flash loan to manipulate pool reserves
// 2. Call contract with manipulated price
// 3. Profit, repay flash loan
Fix: TWAP
// Use time-weighted average price
uint256 price = oracle.consult(token, 1 hours); // 1 hour TWAP
3. Access Control
// VULNERABLE: Missing access control
function setFeeRecipient(address newRecipient) external {
feeRecipient = newRecipient; // Anyone can call!
}
// Fix: Only authorized
function setFeeRecipient(address newRecipient) external onlyOwner {
feeRecipient = newRecipient;
}
Real Exploit Breakdown: Ronin ($600M)
Timeline:
1. Sky Mavis ran 5 of 9 validator nodes
2. Hackers compromised Sky Mavis systems
3. Got 4 keys + 1 from Axie DAO (still had access)
4. 5/9 keys = valid signature
5. Signed withdrawal for 173,600 ETH
6. Went unnoticed for 6 days
What went wrong:
- Centralized validator set (5/9 controlled by one org)
- Poor key management
- No monitoring of large withdrawals
- Old permissions not revoked
Defense Patterns
1. Circuit Breakers y
modifier notPaused() {
require(!paused, "Contract paused");
_;
}
function emergencyPause() external onlyGuardian {
paused = true;
emit Paused(block.timestamp);
}
2. Rate Limiting
uint256 public constant WITHDRAWAL_LIMIT = 1000 ether;
uint256 public dailyWithdrawn;
uint256 public lastWithdrawalDate;
function withdraw(uint256 amount) external {
if (block.timestamp > lastWithdrawalDate + 1 days) {
dailyWithdrawn = 0;
lastWithdrawalDate = block.timestamp;
}
require(dailyWithdrawn + amount <= WITHDRAWAL_LIMIT, "Daily limit");
dailyWithdrawn += amount;
// ... withdraw logic
}
3. Timelocks
function scheduleAction(bytes calldata action) external onlyOwner {
bytes32 id = keccak256(action);
scheduledAt[id] = block.timestamp;
}
function executeAction(bytes calldata action) external onlyOwner {
bytes32 id = keccak256(action);
require(block.timestamp >= scheduledAt[id] + TIMELOCK_DURATION, "Too soon");
// Execute action
}
Common Misconceptions
Myth: “Our code is audited, we’re safe.”
Reality: Audits are point-in-time. Upgrades, parameter changes, and new integrations can introduce vulnerabilities after audit. Continuous security is required.
Myth: “Bug bounties find all bugs.”
Reality: Bug bounties help, but attackers are also looking. Bounties typically pay 10M+. The incentives favor attackers.
Myth: “Immutable contracts are safer.”
Reality: Immutable means you can’t fix bugs either. The right choice depends on your threat model. Upgradeable with proper governance can be safer than immutable with bugs.
Security Checklist
Before interacting with a protocol:
Audit & Testing:
□ Multiple audits from reputable firms
□ Active bug bounty ($100K+ critical)
□ Formal verification on critical paths
Team & Operations:
□ Known team (not fully anon)
□ Multisig admin with timelock
□ Incident response plan published
Economic Security:
□ Oracle manipulation resistant
□ Flash loan attack considered
□ Economic attack vectors analyzed
Track Record:
□ No previous exploits (or good incident response)
□ Time in production (>1 year preferred)
□ Community security involvement
Practice Exercises
Exercise 1: Spot the Bug
function swap(uint256 amount) external {
require(tokenA.transferFrom(msg.sender, address(this), amount));
uint256 amountOut = amount * price / 1e18;
require(tokenB.transfer(msg.sender, amountOut));
}
// What's wrong? (Hint: what if price is manipulated?)
Exercise 2: Attack Analysis
Protocol uses Uniswap spot price for liquidations.
Pool liquidity: $1M
User position: $100K collateral, $50K debt
Can you construct an attack? What would you do?
Exercise 3: Security Review
Pick a protocol you use.
Find and evaluate:
1. Audit reports
2. Bug bounty program
3. Admin key setup
4. Emergency procedures
Key Takeaways
- Most exploits are preventable - Known patterns, known fixes
- Security is ongoing - Audits are snapshots, not guarantees
- Defense in depth - Multiple layers of protection
- Evaluate before trusting - Do your own security review
What’s Next?
🎯 Continue learning: Security Architecture for Trading
🔬 Expert version: DeFi Protocol Security
Now you can evaluate DeFi security systematically. 🔒
Questions about this lesson? Working on related infrastructure?
Let's discuss