Good Contract Audits with ConsenSys Diligence Fuzzing – Fuzzing as a Service

In case you’re working with sensible contracts—and even simply exploring them—you in all probability already know that sensible contract safety is necessary. Good contracts are immutable as soon as deployed, and infrequently contain vital quantities of cash. Writing secure and dependable code earlier than deployment needs to be prime of thoughts. And because the adoption of blockchain accelerates, guaranteeing the safety of sensible contracts turns into much more necessary. 

The most effective additions to your sensible contract audit is fuzzing, a dynamic testing approach that exposes vulnerabilities by producing and injecting random inputs into your sensible contracts throughout testing.

On this article, we’ll discover how one can use fuzzing to successfully audit a wise contract. Particularly, we’ll take a look at ConsenSys Diligence Fuzzing—a brand new fuzzing as a service (FaaS) providing. We’ll delve into the technical elements and present some code examples.

What’s Fuzzing?

Fuzzing is a dynamic testing approach the place random (or semi-random) inputs known as “fuzz” are generated and injected into code. Fuzzing will help reveal bugs and vulnerabilities that weren’t caught by conventional testing strategies.

Handbook (unit) testing requires you to determine what performance to check, what inputs to make use of, and what the anticipated output needs to be. It’s time-consuming, tough, and in the long run, it’s nonetheless simple to overlook situations.

Alternatively, fuzzing (or fuzz testing) is an automatic testing course of that sends random information into an software to check its safety. A fuzzer will help you perceive how a program responds to unpredictable inputs. 

Fuzzing has been round for some time. Defensics and Burp Suite are some examples within the conventional improvement world. There are additionally a number of web3/blockchain fuzzing instruments accessible, resembling Echidna and Foundry. Nevertheless, Diligence Fuzzing is fuzzing as a service and makes every thing somewhat easier to implement. Which in the long run means higher audits and safer contracts. So let’s look into it in additional element.

ConsenSys Diligence Fuzzing

Diligence Fuzzing (by ConsenSys, which can also be behind ecosystem requirements resembling MetaMask and Infura) is a fuzzer constructed for web3 sensible contracts. It: 

  • Works from a proper spec that describes the anticipated habits of your sensible contract

  • Generates transaction sequences that may be capable of violate your assertions

  • Makes use of superior evaluation to seek out inputs that cowl a most quantity of your sensible contract code

  • Validates the enterprise logic of the app and checks for purposeful correctness

  • Gives you with any findings

And all as a service with minimal work from you!

To make use of Diligence Fuzzing observe these three steps:

  1. First, outline your sensible contract specs utilizing Scribble. 

  2. Subsequent, submit the code to Diligence to run your fuzzing. 

  3. Lastly, with the audit report, repair and enhance your code!

Fuzzing in Motion

So let’s try it out and see it in motion. We’ll use the Fuzzing CLI and Scribble to fuzz-test a pattern sensible contract.

Step 1: Join

First, sign up for access to the Diligence Fuzzing. 

Step 2: Set up dependencies

Subsequent, set up the Fuzzing CLI and Scribble. ConsenSys recommends that you’ve got the most recent variations of Node and Python. Be certain you’re utilizing not less than Python 3.6 and Node 16. Then:

pip3 set up diligence-fuzzing
npm i -g eth-scribble ganache truffle

Notice: This requires a Linux, mac, or Linux subsystem with Home windows. Home windows Powershell has some complexities the group is engaged on. You may at all times use a github codespace (which creates a VScode-like-interface with a clear bootstrapped construct) and set up the above conditions by way of command line. 

Step 3: Get an API key

Now you might want to generate an API key to make use of the CLI. Go to the API Keys page and click on on Create new API Key.

Step 4: Arrange fuzzing configuration 

Now we’d like a wise contract to fuzz! As a part of their very own tutorial, ConsenSys gives a pattern sensible contract to make use of. Let’s simply use that one.

git clone https://github.com/ConsenSys/scribble-exercise-1.git

Open the .fuzz.yml file from the challenge and add in your API key for the “key” property at round line 25.

# .fuzz_token.yml

fuzz:
    # Inform the CLI the place to seek out the compiled contracts and compilation artifacts
    build_directory: construct/contracts
    
    # The next handle goes to be the principle goal for the fuzzing marketing campaign
    deployed_contract_address: "0xe78A0F7E598Cc8b0Bb87894B0F60dD2a88d6a8Ab"
    
    # We'll do fuzzing with 2 cores
    number_of_cores: 2
    
    # Run the marketing campaign for simply 3 minutes.
    time_limit: 3m 

    # Put the marketing campaign within the Sribble Train 1 challenge
    challenge: "Scribble Train 1"
    
    # When the marketing campaign is created it's going to get a reputation <prefix>_<random_characters>
    campaign_name_prefix: "ERC20 marketing campaign"
    
    # Level to your ganache node which holds the seed
    rpc_url: "http://localhost:8545"
    
    key: "INSERT YOUR API KEY HERE"

    # That is the contract that the marketing campaign will present protection for/ map points to and so on
    # It is a record of all of the related contracts (don't be concerned about dependencies, we'll get these robotically )
    targets:
        - "contracts/vulnerableERC20.sol"

Notice: Remember to cease your fuzzing campaigns or set a time restrict, or it would run for an unexpectedly very long time. You’ll notice from the above file that we set the time restrict for our campaigns to 3 minutes.

Step 5: Outline fuzzing properties

Discover additionally that now we have our sensible contract: contracts/vulnerableERC20.sol.

Subsequent, we have to outline the properties we would like the fuzzer to verify within the sensible contract. We’ll use Scribble for this step. Scribble is a specification language that interprets high-level specs into Solidity code. It permits you to annotate your contracts with properties after which transforms these annotations into concrete assertions that can be utilized by testing instruments (resembling Diligence Fuzzing). Fairly cool!

We’ll add the highlighted code segments to our contract:

pragma solidity ^0.6.0;

/// #invariant "balances are in sync"
unchecked_sum(_balances) == _totalSupply;
contract VulnerableToken {

This annotation will make sure that our whole provide and balances are in sync.

Step 6: Run

Now we fuzz! Merely run this command:

Step 7: Consider outcomes

After the fuzzer is completed (it would take a minute or two to begin up) we will get our outcomes. We will both use the hyperlink the fuzzer offers us, or we will go to our dashboard.

properties, we will see what’s being fuzzed and any violations. And guess what? We discovered a bug! Click on on the road location button to see the offensive code.

For particulars, click on Present transaction particulars. We will see the fuzzer known as “switch”:

Upon nearer examination, we will now see what precipitated our bug.

The transfer_to and origin arguments are the identical. There should be a safety vulnerability when somebody sends tokens to themselves. Let’s look within the supply code to see what’s improper.

operate switch(handle _to, uint256 _value) exterior returns (bool) 


 handle from = msg.sender;


   require(_value <= _balances[from]);


   uint256 newBalanceFrom = _balances[from] - _value;
   uint256 newBalanceTo = _balances[_to] + _value;


   _balances[from] = newBalanceFrom;
   _balances[_to] = newBalanceTo;


   emit Switch(msg.sender, _to, _value);


   return true;


 

Yep! We will see that when the sender and recipient are the identical, strains 30 and 31 will get somewhat bizarre—one is altering the worth of the ‘from’ account, and one is altering the worth of the ‘to’ account. The code assumes they’re totally different accounts. However since they’re the identical account, by the point we get to line 31, the worth now we have isn’t the worth we count on. It’s already been modified by the earlier line.

We will repair this by including the highlighted strains of code beneath:

operate switch(handle _to, uint256 _value) exterior returns (bool) 
 handle from = msg.sender;
   require(_value <= _balances[from]);


   _balances[from] -= _value;
   _balances[_to] += _value;


   uint256 newBalanceFrom = _balances[from] - _value;
   uint256 newBalanceTo = _balances[_to] + _value;


   _balances[from] = newBalanceFrom;
   _balances[_to] = newBalanceTo;


   emit Switch(msg.sender, _to, _value);


   return true;
 

Listed here are a number of different technical particulars to pay attention to:

  • The seed.js script does some setup be just right for you right here. It deploys the contract to a check node. It may additionally do issues like mint tokens, open swimming pools, and so on. It offers the fuzzer the best state to begin.

  • The yml file has many config parameters that you could discover. Notably the contract handle to fuzz, the API key, the time_limit for the fuzzing, and a few others.

  • The CLI ships with an auto-config generator. Run fuzz generate-config to get some useful Q&A for producing the config.

Good Contract Audits—Use Fuzzing!

Fuzzing and Diligence Fuzzing-as-a-service is a robust device for testing auditing Ethereum blockchain sensible contracts. Whether or not you’re working in decentralized finance (DeFi), NFTs, or simply beginning in sensible contract improvement, it will possibly take you to the subsequent stage of figuring out and fixing vulnerabilities in your sensible contracts. Together with guide critiques, unit checks, guide testing, penetration testing, code critiques, and extra, fuzzing needs to be a key a part of your sensible contract safety audit course of for a safer and sturdy codebase.

Have a extremely nice day!