💻Using the CLI

Fine tuning everything for optimal fuzzing

Fuzz is a command-line tool for smart contract fuzzing. It provides several modes of fuzzing, including smart mode, manual mode, and Foundry tests fuzzing. It is the only way to submit campaign to Diligence Fuzzing.

Installing the CLI

The Diligence Fuzzing CLI runs on Python 3.6+, including 3.8 and pypy3. To install it, simply run:

pip3 install diligence-fuzzing

Subscriptions and API Key

In order to submit campaigns, you need to have an active subscription to Diligence Fuzzing. Pricing plans can be found at https://consensys.net/diligence/fuzzing . To get started you can also use our free trial, which doesn't require a credit card. Subscriptions and Free Trial can be activated at https://fuzzing.diligence.tools/subscription.

Once you have an active subscription, you can go to https://fuzzing.diligence.tools/keys and create a new API key. That key should then be passed to the cli when submitting campaigns.

The best way to configure the API key is by adding it to a .env file in your project's folder.

FUZZ_API_KEY=MY_API_KEY

Remember to add the .env file to your .gitignore so you don't push your API key to version control.

Alternatively you can also:

  • Set the API key as an environment variable called FUZZ_API_KEY;

  • Add the API key to the .fuzz.yaml configuration file (See CLI Configuration);

  • Set the API key as a configuration parameter of the campaign start command fuzz run -k your_api_key_here .

CLI Configuration

The Fuzz CLI tool allows configuration through 4 sources:

  1. .env files

  2. Environment variables

  3. Command options

  4. YAML config files

.env Files and Environment variables

Virtually all of the CLI's configuration parameters can be set as environment variables. A complete list can be found here. These environment variables can also be configured on a .env file on your project's folder.

Remember to add the .env file to your .gitignore so you don't push your API key to version control.

Configuration File

On all but Foundry projects, a configuration file is required. The CLI can automatically generate a configuration file, by running fuzz config generate. You will then be guided through a process to get you going.

The fuzz config generate command will do its best to detect the framework you're using, find the sources and build directory and set some up parameters. You can then manually tweak the file to add or change any parameters.

Below, you can find two examples of configuration files. The first section contains a small sample configuration that will likely be enough to get you started. The second section contains some tips and tricks that you can use to improve your fuzzing configuration and super-charge your fuzzing setup.

Don't worry about the configuration too much. The simple configuration will get you some awesome fuzzing results in no time!

First, below is our base configuration, which you'll recognise from Fuzzing 1-2-3:

# .fuzz_token.yml

analyze:
    # We need to know where the dependencies live
    remappings:
      - "@openzeppelin=./node_modules/@openzeppelin"
fuzz:
    # Tell the CLI which development framework you are using.
    # Currently, the supported values are: truffle, hardhat, brownie, and dapptools
    ide: hardhat
    
    # A project name or previous campaign ID to be used as a starting point.
    corpus_target: myproject
    
    # Scribble no-assertion mode
    no_assert: True
    
    # Tell the CLI where to find the compiled contracts and compilation artifacts
    build_directory: artifacts
    
    # The following address is going to be the main target for the fuzzing campaign
    deployed_contract_address: "0x48b8050b4174f7871ce53AaF76BEAcA765037BFf"
    
    # We'll do fuzzing with 32 cores 🚀
    number_of_cores: 32
    
    # When the campaign is created it'll get a name <prefix>_<random_characters>
    campaign_name_prefix: "my-first-campaign"
    
    # Set the API key, which can be obtained from the Diligence Fuzzing Dashboard
    key: "bHd3...ddsds"
    
    # Point to your Ethereum node which holds the seed deployment 🌱
    rpc_url: "http://localhost:8545"
    
    # Set a time limit, at the end of which the campaign is stopped, e.g., 10minutes , 2hours,  3days
    time_limit: 2hours
    
    # This is the contract that the campaign will show coverage for, map issues to, etc.
    # It's a list of all the relevant contracts (don't worry about dependencies, we'll get those automatically 🙌)
    targets:
        - "contracts/Token.sol"

The following extends the configuration and sets all available configuration options:

# .fuzz_token_full.yml

analyze:
    # We need to know where the dependencies live
    remappings:
      - "@openzeppelin=./node_modules/@openzeppelin"
      - "@ozUpgradesV3=OpenZeppelin/openzeppelin-contracts-upgradeable@3.3.0"
      
    # Sometimes you want to enforce a speecific Solidity version
    solc_version: "0.6.12"
    
fuzz:
    # Tell the CLI where to find the compiled contracts and compilation artifacts
    build_directory: artifacts
    
    # The following address is going to be the main target for the fuzzing campaign
    deployed_contract_address: "0x48b8050b4174f7871ce53AaF76BEAcA765037BFf"

    # This parameter tells the fuzzer to also fuzz these contracts
    additional_contracts_addresses:
        - "0x0eb775F99A28cb591Fa449ca74eF8E7cEd3A609a"
        - "0x21C62e9c9Fcb6622602eBae83b41abb6b28d7256"

    # We'll do fuzzing with 32 cores 🚀
    number_of_cores: 32
    
    # When the campaign is created it'll get a name <prefix>_<random_characters>
    campaign_name_prefix: "my-first-campaign"
    
    # Set a default project to which your campaigns will be attached to
    project: "my project name"
    
    # Set the API key, which can be obtained from the Diligence Fuzzing Dashboard
    key: "bHd3...ddsds"
    
    # Point to your Ethereum node which holds the seed deployment 🌱
    rpc_url: "http://localhost:8545"
    
    # Set a time limit, at the end of which the campaign is stopped, e.g., 10minutes , 2hours,  3days
    time_limit: 2hours
    
    # This is the contract that the campaign will show coverage for, map issues to, etc.
    # It's a list of all the relevant contracts (don't worry about dependencies, we'll get those automatically 🙌)
    targets:
        - "contracts/Token.sol"

Tips and Tricks

Make sure you have the right additional_contracts_addresses

If you forget to add a crucial component to your additional_contracts_addresses then the fuzzer will ignore that contract. Unfortunately, that can result in parts of your system not being explored by the fuzzer. To avoid this, make sure to add the addresses of all relevant components!

Last updated