# Aderyn — Solidity के लिए नया Rust-Based Static Analyzer
Static analysis tools smart contract security का backbone हैं। Slither लंबे समय से industry standard रहा है, लेकिन Cyfrin का Aderyn एक नया competitor है जो Rust में लिखा गया है और modern workflow के लिए optimized है।
Aderyn क्या है?
Aderyn एक Rust-based static analyzer है जो Solidity code को scan करके common vulnerabilities, anti-patterns, और optimization opportunities detect करता है।
Key Features
Project Background
- Developer: Cyfrin (Patrick Collins की security team)
- Language: Rust
- License: MIT
- First Release: August 2023
- Current Status: Active development, production-ready
Installation
Prerequisites
# Rust installed होना चाहिए
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Install via Cargo
cargo install aderyn
# Verify installation
aderyn --version
Install via Binary (Alternative)
# Linux/macOS
curl -L https://github.com/Cyfrin/aderyn/releases/latest/download/aderyn-x86_64-unknown-linux-gnu -o aderyn
chmod +x aderyn
sudo mv aderyn /usr/local/bin/
# Verify
aderyn --version
Basic Usage
Simple Scan
# Current directory
aderyn .
# Specific path
aderyn ./src
# With output file
aderyn . -o report.md
Configuration File
// aderyn.config.json
{
"root": "./src",
"exclude": ["test/", "script/"],
"output": "aderyn-report.md",
"remappings": [
"@openzeppelin/=lib/openzeppelin-contracts/",
"forge-std/=lib/forge-std/src/"
]
}
# Use config
aderyn --config aderyn.config.json
Detection Capabilities
1. Reentrancy Detection
// Vulnerable contract
contract VulnerableBank {
mapping(address => uint256) public balances;
function withdraw() public {
uint256 amount = balances[msg.sender];
// ❌ Aderyn detects: External call before state update
(bool success, ) = msg.sender.call{value: amount}("");
require(success);
balances[msg.sender] = 0;
}
}
Aderyn output:
## High Severity
[H-1] Potential Reentrancy Vulnerability
Description: External call made before state variable update
Location: VulnerableBank.sol:6-8
Recommendation: Update state before external calls (Checks-Effects-Interactions pattern)
2. Unchecked Return Values
contract TokenTransfer {
IERC20 public token;
function transferTokens(address to, uint256 amount) public {
// ❌ Aderyn detects: Unchecked return value
token.transfer(to, amount);
}
}
Detection:
## Medium Severity
[M-1] Unchecked ERC20 Transfer
Location: TokenTransfer.sol:5
Recommendation: Use SafeERC20 or check return value
3. Centralization Risks
contract CentralizedToken {
address public owner;
// ❌ Aderyn detects: Dangerous owner privileges
function mint(address to, uint256 amount) public {
require(msg.sender == owner);
_mint(to, amount);
}
function setOwner(address newOwner) public {
require(msg.sender == owner);
owner = newOwner;
}
}
4. Gas Optimization Opportunities
contract GasWaster {
uint256[] public data;
// ❌ Aderyn suggests: Cache array length
function sumData() public view returns (uint256 sum) {
for (uint256 i = 0; i < data.length; i++) {
sum += data[i];
}
}
}
Aderyn vs Slither: Comparison
Speed Benchmark
# Project: Uniswap V3 Core (~3000 lines)
# Slither
time slither .
# Real: 12.4s
# Aderyn
time aderyn .
# Real: 1.8s
# Result: Aderyn ~7x faster
Detection Coverage
| Category | Slither | Aderyn | Winner |
|----------|---------|--------|--------|
| Reentrancy | ✅ Excellent | ✅ Excellent | Tie |
| Access Control | ✅ Good | ✅ Good | Tie |
| Gas Optimization | ✅ 50+ checks | ⚠️ 20+ checks | Slither |
| False Positives | ⚠️ High | ✅ Low | Aderyn |
| Unchecked Calls | ✅ Good | ✅ Excellent | Aderyn |
| Custom Detectors | ✅ Python | ✅ Rust | Preference |
Output Quality
Slither:
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities
VulnerableBank.withdraw() (VulnerableBank.sol#5-11) sends eth to arbitrary user
Dangerous calls:
- (success) = msg.sender.call{value: amount}() (VulnerableBank.sol#8)
Aderyn:
## High - Reentrancy Vulnerability
Contract: VulnerableBank
Function: withdraw()
Severity: HIGH
Confidence: HIGH
External call to untrusted address before state update:
- Line 8: msg.sender.call{value: amount}("")
- Line 10: balances[msg.sender] = 0
Fix: Apply Checks-Effects-Interactions pattern
solidity
function withdraw() public {
uint256 amount = balances[msg.sender];
balances[msg.sender] = 0; // State update first
(bool success, ) = msg.sender.call{value: amount}("");
require(success);
}
Winner: Aderyn (better formatting, includes fix)
Integration
| Feature | Slither | Aderyn |
|---------|---------|--------|
| Hardhat | ✅ Native | ⚠️ Manual |
| Foundry | ⚠️ Via plugin | ✅ Native |
| CI/CD | ✅ Easy | ✅ Easy |
| VS Code | ✅ Extension | ❌ Not yet |
Real-World Example: Full Scan
// contracts/VulnerableVault.sol
contract VulnerableVault {
mapping(address => uint256) public deposits;
address public admin;
constructor() {
admin = msg.sender;
}
function deposit() public payable {
deposits[msg.sender] += msg.value;
}
function withdraw(uint256 amount) public {
require(deposits[msg.sender] >= amount);
(bool success, ) = msg.sender.call{value: amount}("");
require(success);
deposits[msg.sender] -= amount;
}
function emergencyWithdraw() public {
require(msg.sender == admin);
payable(admin).transfer(address(this).balance);
}
function updateAdmin(address newAdmin) public {
require(msg.sender == admin);
admin = newAdmin;
}
}
Run Aderyn
aderyn contracts/ -o vault-report.md
Generated Report
# Aderyn Analysis Report
Summary
- High: 1
- Medium: 2
- Low: 3
- Gas: 1
---
High Severity Issues
[H-1] Reentrancy in withdraw()
Location: VulnerableVault.sol:14-20
Issue: External call before state update allows reentrancy
Recommendation:
solidity
function withdraw(uint256 amount) public {
require(deposits[msg.sender] >= amount);
deposits[msg.sender] -= amount; // Move before call
(bool success, ) = msg.sender.call{value: amount}("");
require(success);
}
---
Medium Severity Issues
[M-1] Centralization Risk - Admin Privileges
Location: VulnerableVault.sol:22-25
Issue: Admin can drain all funds via emergencyWithdraw()
Recommendation: Use multi-sig or governance
[M-2] Missing Access Control Modifier
Location: VulnerableVault.sol:27-30
Issue: Admin update logic scattered, error-prone
Recommendation: Create Ownable modifier
---
Low Severity Issues
[L-1] Use transfer() Instead of call()
Location: VulnerableVault.sol:17
Issue: call() forwards all gas, risky
Recommendation: Use transfer() or limit gas
[L-2] Missing Event Emissions
Locations: deposit(), withdraw()
Recommendation: Emit events for off-chain tracking
---
Gas Optimizations
[G-1] Cache Storage Variable
Location: emergencyWithdraw()
Current:
solidity
payable(admin).transfer(address(this).balance);
Optimized:solidity
address cachedAdmin = admin;
payable(cachedAdmin).transfer(address(this).balance);
Savings: ~100 gas
CI/CD Integration
GitHub Actions
# .github/workflows/security.yml
name: Security Analysis
on: [push, pull_request]
jobs:
aderyn:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Aderyn
run: |
cargo install aderyn
- name: Run Analysis
run: |
aderyn . -o aderyn-report.md
- name: Upload Report
uses: actions/upload-artifact@v3
with:
name: aderyn-report
path: aderyn-report.md
- name: Fail on High Severity
run: |
if grep -q "High:" aderyn-report.md; then
echo "High severity issues found!"
exit 1
fi
Advanced: Custom Detectors
Aderyn extensible है — Rust में custom detectors लिख सकते हैं:
// custom_detector.rs
use aderyn::detector::{Detector, Finding, Severity};
pub struct CustomDetector;
impl Detector for CustomDetector {
fn detect(&self, context: &Context) -> Vec<Finding> {
// Your detection logic
vec![]
}
}
Limitations
Should You Use Aderyn?
Use Aderyn if:
- Foundry-based project
- Speed matters (CI/CD)
- Low false positives important
- Modern, clean reports चाहिए
Use Slither if:
- Maximum detector coverage चाहिए
- Hardhat project
- Python ecosystem में comfortable
- VS Code integration important
Best approach: दोनों use करें!
# Run both
slither . --json slither-report.json
aderyn . -o aderyn-report.md
# Compare outputs
Conclusion
Aderyn एक promising tool है जो speed और accuracy में excel करता है। यह Slither का replacement नहीं, बल्कि complement है।
Key takeaways:
- ~7x faster than Slither
- Better formatted reports
- Foundry-native integration
- Lower false positives
- Still maturing ecosystem
अगली audit में दोनों tools try करें — different perspectives often hidden bugs reveal करते हैं।