Detectors Quickstart
Aderyn makes it easy to build Static Analysis detectors that can adapt to any Solidity codebase and protocol. This guide will teach you how to build, test, and run your custom Aderyn detectors.
Prerequisites
Before starting to create your custom Aderyn detectors, ensure you have the following:
Rust: Aderyn is built in Rust, so you must install Rust and Cargo (Rust's package manager) before running it. If you haven't installed Rust yet, follow the instructions on the official Rust website.
Suggested VSCode extensions:
rust-analyzer - Rust language support for Visual Studio Code
Rust Syntax - Improved Rust syntax highlighting
If you haven't yet, read the Aderyn quickstart and what is a detector documentation before getting started.
Step: 1 Clone the Aderyn repository
Navigate to the official Aderyn repository, clone the repository, and open it in your favorite code editor:
Once cloned, this is how, simplified, your folder structure will look like:
Source: https://github.com/Cyfrin/aderyn
The folders and files you should be familiar with when developing your custom Aderyn detectors are:
report.md
: The standard report generated by Aderyn on the contracts contained in thetests
directory_template.rs
: The template used to create new detectorsdetect
: The folder containing the detectors and dependenciesdetectors.rs
: exposes a list of detectors to be called by Aderyn/high and /low folders
: contains the detectors used by Aderyn divided by severitymod.rs
: exposes a list of detectors to be called inside thedetectors.rs
file
tests
: contains sample contracts usually used to testing your detectors.
Now that our Aderyn cloned project is ready, let's see how to create our first detector.
Step 2: Create a new detector file using the template
Navigate to the aderyn_core/src/detect/low
folder, and create a new copy of the _template.rs
file named my_first_detector.rs
Inside the detector's template, you will find the following code:
As we've seen in the What is a detector section - in the code above, we are:
Declaring a new detector named
TemplateDetector
Implementing an Issue detector with inside the following functions:
detect(): containing the logic to detect a given vulnerability pattern
severity(): the severity associated with the vulnerability that will appear in the report
title(): the title of the vulnerability that will be used for the report
description(): the description of the vulnerability
instances(): internal function that returns the instances found by the detector (don't change this)
name(): title of the vulnerability in kebab-case
Refer to the Detectors API Reference for an in-depth look at how every function works.
Before moving forward, let's rename our detector from TemplateDetector to MyFirstDetector.
Inside your my_first_detector.rs file, navigate to line 21, find the pub struct TemplateDetector
and rename it to MyFirstDetector
.
Then find the impl IssueDetector for TemplateDetector
and rename it to impl IssueDetector for MyFirstDetector
.
and also in the implementation
Step 3: Add your Detector to the mod.rs file
If you have installed the VSCode extensions suggested in the prerequisites, you will notice that the linter gives us some errors. To solve this, you will need to add the newly created detector to the mod.rs
file, which will, in return, make the right dependencies available to your detector.
To do this, you'll first need to move the detector file inside the aderyn_code/src/detect/low
folder, and open the low/mod.rs
file.
Here, we will have to import our newly created detector:
This should make sure all the dependencies are available to your detector. With that, you can now start editing the detector:
Step 4: Write your custom detector
Let's say we want to build a detector that checks whether a function has or not "useless" modifiers.
Back in my_first_detector.rs
, inside the IssueDetector
, copy and paste the following code:
Source: https://github.com/Cyfrin/aderyn/blob/dev/aderyn_core/src/detect/low/useless_modifier.rs
The first thing you can notice is the detect() function, inside of which we're using our WorkspaceContext to find all modifier_definitions
and modifier_invocations
inside the AST.
For each definition, we then check all the invocations, and if a defined modifier has no invocations, it's redundant and should be removed from the code. When this happens, we call the capture() function that will add it to the final report, together with the information defined inside the functions:
You can find more examples of detectors inside the official GitHub repo.
Once that's done, we call the Ok function, passing true or false based on whether the found_instances array has items in it or not.
If you're nervous about whether or not this detector is working correctly, we suggest you learn how to test your Aderyn detectors. You'll want this to be your next step after following this quickstart anyways.
Step 5: Register your detector
Now that your detector is ready to be used, it's time to add it to Aderyn and make sure the new detector is called when the aderyn .
the command is run.
First of all, open the detectors.rs
file inside aderyn_core/src/detect/detector.rs
and add your detector to the "low" vulnerability group as follows:
Source: https://github.com/Cyfrin/aderyn/blob/dev/aderyn_core/src/detect/detector.rs#L4
Then find the get_all_issue_detectors
function and add your detector to the vector returned by it:
Source:https://github.com/Cyfrin/aderyn/blob/dev/aderyn_core/src/detect/detector.rs#L31
Then, find IssueDetectorNamePool
in detector.rs
and add our MyFirstDetector
to the list:
Lastly, add your custom detector to the detector_name
match
statement inside the request_issue_detector_by_name
function:
Source: https://github.com/Cyfrin/aderyn/blob/dev/aderyn_core/src/detect/detector.rs#L106
Well done! Now your detector will be registered and run every time Aderyn is run locally π
Now it's time to run our newly created detector!
Step 6: Run your custom detector locally
Once your detector has been registered, you can run it locally against any Foundry-based Solidity smart contract codebase.
Similarly to what is explained in the Aderyn quickstart guide, you can copy and paste the following command in your terminal to run your local Aderyn version, including your custom detectors:
Running the code above will call all Aderyn detectors, including your custom detectors. This will add a new vulnerability, a report.md
file, as specified in the runner.rs
.
If you want to run your custom detectors using the standard aderyn .
command, check out the contributions guidelines and open a PR following the guidelines.
You'll now see your new detector printed out at the end of the report.md
!
Step 7: Test your detector
If you haven't already, learn how to test your Aderyn detectors. Your detector isn't done, and it won't be merged unless tests have been written for it!
Last updated