Problem: Manual Audits Miss Critical Vulnerabilities
You're deploying a Solidity contract handling real funds, but manual code review missed a reentrancy vulnerability that could drain your protocol.
You'll learn:
- How to use AI for systematic vulnerability scanning
- Which attack patterns AI catches vs. misses
- How to combine AI with traditional tools for production readiness
Time: 20 min | Level: Intermediate
Why This Happens
Smart contract audits require checking for dozens of vulnerability patterns across complex codebases. Human reviewers focus on business logic and miss subtle patterns like:
Common blind spots:
- Reentrancy with non-obvious external calls
- Integer overflow in Solidity <0.8.0
- Access control bypasses in multi-contract systems
- Front-running vulnerabilities in DeFi protocols
AI models trained on exploit databases can pattern-match these systematically.
Solution
Step 1: Prepare Your Contract for Analysis
# Install dependencies
npm install --save-dev @openzeppelin/contracts
forge install foundry-rs/forge-std
# Compile to catch syntax issues first
forge build
Expected: Clean compilation. Fix compiler errors before AI analysis.
If it fails:
- Error: "Solidity version mismatch": Update
foundry.tomlto match your pragma
Step 2: Create an AI Audit Prompt
# Save as audit-prompt.md
Analyze this Solidity contract for vulnerabilities. Focus on:
1. **Reentrancy:** External calls that allow recursive re-entry
2. **Access Control:** Functions missing proper authorization
3. **Integer Issues:** Overflow/underflow (if Solidity <0.8.0)
4. **Front-Running:** Transaction ordering dependencies
5. **Gas Optimization:** Unnecessary SLOAD operations
For each issue:
- Severity: Critical | High | Medium | Low
- Line numbers
- Exploit scenario
- Recommended fix
Contract:
Why this works: Structured prompts get specific, actionable results instead of generic security advice.
Step 3: Run AI Analysis with Claude or GPT-4
# Using Claude API (example with Python)
cat > audit.py << 'EOF'
import anthropic
import os
client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
# Read your contract
with open("src/MyContract.sol", "r") as f:
contract_code = f.read()
with open("audit-prompt.md", "r") as f:
prompt = f.read()
message = client.messages.create(
model="claude-sonnet-4-20250514", # Best for code analysis
max_tokens=4000,
messages=[
{"role": "user", "content": f"{prompt}\n\n```solidity\n{contract_code}\n```"}
]
)
# Save audit report
with open("audit-report.md", "w") as f:
f.write(message.content[0].text)
print("✓ Audit complete. Check audit-report.md")
EOF
python audit.py
Expected: AI returns structured findings with severity ratings.
Step 4: Verify AI Findings with Static Analysis
# Install Slither (Trail of Bits tool)
pip install slither-analyzer --break-system-packages
# Run automated checks
slither . --exclude-dependencies
# Compare with AI findings
diff <(grep -o "Line [0-9]*" audit-report.md | sort) \
<(slither . --json - | jq '.results[].check' | sort)
Why both tools: AI catches logic flaws, Slither catches known patterns. Use both.
If it fails:
- Slither reports false positives: Check if AI agrees. False positives common in proxy patterns.
Step 5: Analyze a Real Example
Here's a vulnerable contract AI should catch:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract VulnerableBank {
mapping(address => uint256) public balances;
function deposit() public payable {
balances[msg.sender] += msg.value;
}
// ❌ CRITICAL: Reentrancy vulnerability
function withdraw(uint256 amount) public {
require(balances[msg.sender] >= amount, "Insufficient balance");
// External call BEFORE state update
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "Transfer failed");
balances[msg.sender] -= amount; // Too late!
}
}
AI should identify:
**CRITICAL: Reentrancy in withdraw() - Line 15**
Severity: Critical
Impact: Complete fund drainage
Exploit:
1. Attacker calls withdraw()
2. Fallback function re-enters withdraw()
3. Balance check passes (not updated yet)
4. Process repeats until contract drained
Fix:
- Move balance update before external call (Checks-Effects-Interactions pattern)
- Or use ReentrancyGuard from OpenZeppelin
Corrected version:
function withdraw(uint256 amount) public {
require(balances[msg.sender] >= amount, "Insufficient balance");
// Update state FIRST
balances[msg.sender] -= amount;
// Then make external call
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "Transfer failed");
}
Step 6: Test the Fix
// test/VulnerableBank.t.sol
pragma solidity ^0.8.20;
import "forge-std/Test.sol";
import "../src/VulnerableBank.sol";
contract Attacker {
VulnerableBank public bank;
uint256 public attackCount;
constructor(address _bank) {
bank = VulnerableBank(_bank);
}
receive() external payable {
// Try to re-enter (should fail with fixed version)
if (attackCount < 3) {
attackCount++;
bank.withdraw(1 ether);
}
}
function attack() public payable {
bank.deposit{value: msg.value}();
bank.withdraw(1 ether);
}
}
contract VulnerableBankTest is Test {
VulnerableBank public bank;
function testReentrancyPrevented() public {
bank = new VulnerableBank();
Attacker attacker = new Attacker(address(bank));
// Fund bank
vm.deal(address(bank), 10 ether);
// Attacker deposits 1 ETH
vm.deal(address(attacker), 1 ether);
attacker.attack{value: 1 ether}();
// With fix: attacker should only withdraw once
assertEq(address(bank).balance, 10 ether); // Bank funds safe
}
}
# Run test
forge test --match-test testReentrancyPrevented -vvv
# Should pass with fixed version
Verification
Run complete audit workflow:
# 1. AI analysis
python audit.py
# 2. Static analysis
slither . --exclude-dependencies
# 3. Automated tests
forge test
# 4. Generate coverage report
forge coverage --report summary
You should see:
- AI report with prioritized findings
- Slither confirmation of critical issues
- 100% test coverage on fixed functions
- No critical vulnerabilities remaining
What You Learned
AI strengths:
- Logic flaws in business code (auction rigging, voting manipulation)
- Complex reentrancy patterns across multiple contracts
- Explaining WHY code is vulnerable (not just flagging)
AI limitations:
- Doesn't verify on-chain bytecode matches source
- May miss novel attack vectors (zero-days)
- Can't assess economic attack feasibility
When NOT to rely solely on AI:
- High-value protocols (>$10M TVL) need human auditors
- Novel DeFi mechanics (AI trained on existing exploits)
- Contracts with upgradability or governance
Production checklist:
- AI audit (this guide)
- Slither/Mythril automated tools
- Unit tests with >90% coverage
- Professional audit firm (for mainnet)
- Bug bounty program post-launch
Real-World AI Audit Workflow
# Complete production audit script
cat > full-audit.sh << 'EOF'
#!/bin/bash
set -e
echo "🔍 Starting comprehensive audit..."
# 1. Compile and check dependencies
echo "Step 1: Compilation"
forge build
# 2. AI analysis
echo "Step 2: AI audit (Claude)"
python audit.py
# 3. Static analysis
echo "Step 3: Slither"
slither . --exclude-dependencies --json slither-report.json
# 4. Test coverage
echo "Step 4: Test coverage"
forge coverage --report lcov
# 5. Gas optimization check
echo "Step 5: Gas report"
forge test --gas-report
# 6. Generate summary
cat > AUDIT_SUMMARY.md << 'SUMMARY'
# Audit Results - $(date)
## Critical Issues
$(grep -A 5 "CRITICAL" audit-report.md || echo "None found")
## High Severity
$(grep -A 5 "HIGH" audit-report.md || echo "None found")
## Coverage
$(forge coverage --report summary)
## Next Steps
- [ ] Fix critical issues
- [ ] Re-run tests
- [ ] Schedule professional audit
SUMMARY
echo "✅ Audit complete. Check AUDIT_SUMMARY.md"
EOF
chmod +x full-audit.sh
./full-audit.sh
Tools Comparison (2026)
| Tool | Best For | Limitations | Cost |
|---|---|---|---|
| Claude Sonnet 4 | Logic flaws, explaining exploits | Needs specific prompts | $15/M tokens |
| GPT-4 | Pattern matching, known CVEs | Less detailed explanations | $30/M tokens |
| Slither | Standard vulnerabilities | Many false positives | Free |
| Mythril | Bytecode-level issues | Slow on large contracts | Free |
| Certora | Formal verification | Requires spec writing | Enterprise |
Recommended stack:
- AI for initial triage (Claude Sonnet 4)
- Slither for validation
- Manual review of AI + Slither overlap
- Professional firm for mainnet
Common Vulnerabilities AI Catches Well
1. Reentrancy
// AI detects: external call before state update
(bool success,) = recipient.call{value: amount}("");
balance -= amount; // ❌ Too late
2. Unchecked Return Values
// AI detects: ignored return value
token.transfer(recipient, amount); // ❌ Should check success
3. Access Control
// AI detects: missing modifier
function withdraw() public { // ❌ Anyone can call
// Should be onlyOwner
}
4. Integer Overflow (Solidity <0.8.0)
// AI detects: unchecked arithmetic
uint256 total = balance + amount; // ❌ Can overflow
5. Front-Running
// AI detects: MEV vulnerability
function buyTokens() public payable {
uint256 price = getCurrentPrice(); // ❌ Sandwich attack risk
// Price can change before tx mines
}
Pro Tips
Prompt engineering for better results:
# ❌ Vague prompt
"Check this contract for security issues"
# ✅ Specific prompt
"Analyze for reentrancy in functions with external calls.
For each finding, provide:
1. Attack scenario with example addresses
2. Profit calculation for attacker
3. Solidity 0.8+ compatible fix"
Handling false positives:
// AI may flag this as reentrancy
function safeWithdraw() public nonReentrant {
// OpenZeppelin guard makes this safe
(bool success,) = msg.sender.call{value: balance}("");
}
// Tell AI in comments:
// @audit This is safe - nonReentrant modifier prevents reentrancy
Version-specific analysis:
# Tell AI your Solidity version
"This contract uses Solidity 0.8.20.
Ignore overflow checks (built-in since 0.8.0).
Focus on reentrancy and access control."
Tested with Claude Sonnet 4, Solidity 0.8.20, Foundry, Slither 0.10.0 Sample contracts available at: github.com/example/ai-audit-examples