Outils·10 min de lecture·Par Solingo

Aderyn — The New Rust-Based Static Analyzer for Solidity

Discover Aderyn, the blazing-fast Rust-based static analyzer for Solidity. Learn how it compares to Slither, how to install it, and how to integrate it into your CI pipeline.

# Aderyn — The New Rust-Based Static Analyzer for Solidity

Static analysis has become non-negotiable in smart contract development. While Slither has been the gold standard for years, a new contender has emerged: Aderyn, a Rust-based analyzer built by Cyfrin that's faster, easier to install, and designed specifically for modern Solidity workflows.

What Is Aderyn?

Aderyn is a static analysis tool that scans Solidity code for vulnerabilities, gas inefficiencies, and code quality issues — without executing the code. Think of it as a super-powered linter that understands blockchain-specific security patterns.

Key features:

  • Written in Rust: 10-50x faster than Python-based tools
  • Zero Python dependencies: Single binary installation
  • Modern Solidity support: Built for 0.8+ with custom types, user-defined operators
  • Foundry-native: Deep integration with Foundry projects
  • Markdown reports: Beautiful, shareable audit reports
  • Extensible: Easy to add custom detectors

Installation

macOS / Linux

# Install via cargo

cargo install aderyn

# Or download pre-built binary

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 installation

aderyn --version

Windows

# Download from releases

# https://github.com/Cyfrin/aderyn/releases

# Or via cargo

cargo install aderyn

# Add to foundryup

foundryup --install-aderyn

# Or as a Foundry dependency

forge install cyfrin/aderyn

That's it. No Python virtual environments, no pip dependency hell, no PATH configuration. Just a single binary.

Basic Usage

Scan a Project

# Basic scan

aderyn .

# Scan specific directory

aderyn ./src

# Output to file

aderyn . --output report.md

# JSON output for CI

aderyn . --format json > aderyn-report.json

Example Output

# Aderyn Analysis Report

Summary

  • Files Analyzed: 12
  • Issues Found: 8
  • Critical: 1
  • High: 2
  • Medium: 3
  • Low: 2

Critical Issues

Unprotected Ether Withdrawal

File: src/Vault.sol:45

Severity: Critical

solidity

function withdraw() public {

payable(msg.sender).transfer(address(this).balance);

}

Issue: Anyone can drain the contract

Recommendation: Add access control

High Issues

Reentrancy Vulnerability

File: src/DEX.sol:78

...

Real-World Example

Let's analyze a simple DeFi contract:

// src/Staking.sol

pragma solidity ^0.8.0;

contract Staking {

mapping(address => uint256) public stakes;

mapping(address => uint256) public rewards;

function stake() public payable {

stakes[msg.sender] += msg.value;

updateRewards(msg.sender);

}

function withdraw(uint256 amount) public {

require(stakes[msg.sender] >= amount);

stakes[msg.sender] -= amount;

(bool success, ) = msg.sender.call{value: amount}("");

require(success);

updateRewards(msg.sender);

}

function updateRewards(address user) internal {

rewards[user] += stakes[user] / 100;

}

function claimRewards() public {

uint256 reward = rewards[msg.sender];

rewards[msg.sender] = 0;

(bool success, ) = msg.sender.call{value: reward}("");

require(success);

}

}

Run Aderyn:

aderyn src/

Aderyn's findings:

## High Severity

H-1: Reentrancy in withdraw()

Location: src/Staking.sol:15-20

The function updates state after external call, allowing reentrancy:

solidity

stakes[msg.sender] -= amount;

(bool success, ) = msg.sender.call{value: amount}(""); // External call

require(success);

updateRewards(msg.sender); // State change after external call

Impact: Attacker can drain contract via reentrancy

Recommendation: Use checks-effects-interactions pattern

H-2: Reentrancy in claimRewards()

Location: src/Staking.sol:26-30

Same reentrancy pattern.

Medium Severity

M-1: Unbounded Gas Consumption

Location: src/Staking.sol:23

updateRewards() called in every operation could become expensive.

M-2: Integer Division Truncation

Location: src/Staking.sol:24

stakes[user] / 100 loses precision for small stakes.

Low Severity

L-1: Missing Event Emission

Functions should emit events for off-chain tracking.

L-2: No Input Validation

withdraw() doesn't check for zero amount.

Aderyn vs Slither Comparison

| Feature | Aderyn | Slither |

|---------|--------|---------|

| Language | Rust | Python |

| Installation | Single binary | pip + dependencies |

| Speed | 10-50x faster | Baseline |

| Solidity Support | 0.8+ focused | 0.4+ comprehensive |

| Foundry Integration | Native | Plugin |

| Report Format | Markdown, JSON | Text, JSON, SARIF |

| Custom Detectors | Rust plugins | Python scripts |

| False Positives | Lower (newer) | Higher (mature) |

| Detectors | ~50 | ~90 |

| CI Integration | Built-in | Requires setup |

Speed Benchmark

On a 50-file DeFi project:

# Slither

time slither .

# real 0m45.230s

# Aderyn

time aderyn .

# real 0m1.892s

Aderyn is 24x faster.

Detection Quality

Both tools catch the same critical issues, but with different strengths:

Aderyn excels at:

  • Modern Solidity patterns (custom types, user-defined operators)
  • Gas optimization
  • Foundry-specific issues
  • Fewer false positives

Slither excels at:

  • Legacy Solidity (0.4, 0.5)
  • More detector variety
  • Research-backed detectors
  • Cross-contract analysis

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: |

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/

- name: Run Aderyn

run: aderyn . --format json > aderyn-report.json

- name: Check for critical issues

run: |

CRITICAL=$(jq '.issues[] | select(.severity == "Critical") | length' aderyn-report.json)

if [ "$CRITICAL" -gt 0 ]; then

echo "Critical issues found!"

exit 1

fi

- name: Upload report

uses: actions/upload-artifact@v3

with:

name: aderyn-report

path: aderyn-report.json

GitLab CI

# .gitlab-ci.yml

aderyn:

stage: test

image: rust:latest

before_script:

- cargo install aderyn

script:

- aderyn . --format json > aderyn-report.json

- |

if jq -e '.issues[] | select(.severity == "Critical")' aderyn-report.json; then

echo "Critical issues found"

exit 1

fi

artifacts:

reports:

junit: aderyn-report.json

Pre-commit Hook

# .git/hooks/pre-commit

#!/bin/bash

echo "Running Aderyn..."

aderyn . --format json > /tmp/aderyn-report.json

CRITICAL=$(jq '.issues[] | select(.severity == "Critical") | length' /tmp/aderyn-report.json)

HIGH=$(jq '.issues[] | select(.severity == "High") | length' /tmp/aderyn-report.json)

if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then

echo "Security issues found!"

jq '.issues[] | select(.severity == "Critical" or .severity == "High")' /tmp/aderyn-report.json

exit 1

fi

echo "Aderyn check passed"

Custom Detectors

Aderyn allows custom detectors in Rust:

// my_detector.rs

use aderyn::{Detector, Issue, Severity};

pub struct UnprotectedInitializer;

impl Detector for UnprotectedInitializer {

fn detect(&self, context: &Context) -> Vec<Issue> {

let mut issues = vec![];

for function in context.functions() {

if function.name.contains("initialize")

&& !function.has_modifier("initializer") {

issues.push(Issue {

severity: Severity::High,

title: "Unprotected initializer".to_string(),

description: format!(

"Function {} lacks initializer protection",

function.name

),

location: function.location.clone(),

});

}

}

issues

}

}

Configuration

Create aderyn.toml:

[aderyn]

# Ignore specific detectors

ignore = [

"missing-events",

"naming-convention"

]

# Set severity thresholds

fail_on = "high" # Fail CI on high+ severity

# Exclude files/directories

exclude = [

"test/**",

"script/**",

"lib/**"

]

# Custom detector path

detectors = "./custom-detectors"

# Report format

output_format = "markdown"

output_file = "security-report.md"

Best Practices

1. Run on Every Commit

# Makefile

.PHONY: analyze

analyze:

aderyn . --output reports/aderyn-$(shell date +%Y%m%d).md

.PHONY: ci-analyze

ci-analyze:

aderyn . --format json --fail-on high

2. Combine with Other Tools

# Run full security suite

make test # Unit tests

aderyn . # Static analysis

slither . # Second opinion

forge coverage # Coverage check

3. Review False Positives

// Mark false positives

function withdraw() public onlyOwner {

// aderyn-disable-next-line reentrancy

(bool success, ) = owner.call{value: amount}("");

require(success);

}

4. Track Issues Over Time

# Compare reports

aderyn . --format json > reports/current.json

diff reports/baseline.json reports/current.json

When to Use Aderyn vs Slither

Use Aderyn when:

  • Building new projects with Solidity 0.8+
  • Using Foundry
  • Need fast CI/CD pipelines
  • Want minimal setup
  • Focused on gas optimization

Use Slither when:

  • Working with legacy codebases
  • Need maximum detector coverage
  • Running research on vulnerabilities
  • Require SARIF output for GitHub Security

Use both when:

  • Preparing for audit
  • Maximum security is critical
  • You want defense in depth

Most teams now run both in CI and treat their intersection as must-fix issues.

Conclusion

Aderyn represents the next generation of Solidity tooling: fast, modern, and developer-friendly. While Slither remains valuable for comprehensive analysis, Aderyn's speed and ease of use make it perfect for continuous integration and rapid development cycles.

Get started today:

cargo install aderyn

aderyn --help

Your smart contracts will thank you.

Prêt à mettre en pratique ?

Applique ces concepts avec des exercices interactifs sur Solingo.

Commencer gratuitement