Fuzzing Configuration - Building Secure Contracts (original) (raw)

Building Secure Contracts

Fuzzing Configuration

The fuzzing configuration defines the parameters for the fuzzing campaign.

workers

workerResetLimit

timeout

testLimit

shrinkLimit

callSequenceLength

coverageEnabled

corpusDirectory

coverageFormats

revertReporterEnabled

targetContracts

predeployedContracts

targetContractsBalances

constructorArgs

deployerAddress

senderAddresses

blockNumberDelayMax

blockTimestampDelayMax

blockGasLimit

transactionGasLimit

Using constructorArgs

There might be use cases where contracts in targetContracts have constructors that accept arguments. The constructorArgsconfiguration option allows you to specify those arguments. constructorArgs is a nested dictionary that maps contract name -> variable name -> variable value. Let's look at an example below:

// This contract is used to test deployment of contracts with constructor arguments.
contract TestContract {
    struct Abc {
        uint a;
        bytes b;
    }

    uint x;
    bytes2 y;
    Abc z;

    constructor(uint _x, bytes2 _y, Abc memory _z) {
        x = _x;
        y = _y;
        z = _z;
    }
}

contract DependentOnTestContract {
    address deployed;

    constructor(address _deployed) {
        deployed = _deployed;
    }
}

In the example above, we have two contracts TestContract and DependentOnTestContract. You will note thatDependentOnTestContract requires the deployment of TestContract first so that it can accept the address of whereTestContract was deployed. On the other hand, TestContract requires _x, _y, and _z. Here is what theconstructorArgs value would look like for the above deployment:

Note: The example below has removed all the other project configuration options outside of targetContracts andconstructorArgs

{
  "fuzzing": {
    "targetContracts": ["TestContract", "DependentOnTestContract"],
    "constructorArgs": {
      "TestContract": {
        "_x": "123456789",
        "_y": "0x5465",
        "_z": {
          "a": "0x4d2",
          "b": "0x54657374206465706c6f796d656e74207769746820617267756d656e7473"
        }
      },
      "DependentOnTestContract": {
        "_deployed": "DeployedContract:TestContract"
      }
    }
  }
}

First, let us look at targetContracts. As mentioned in the documentation for targetContracts, the order of the contracts in the array determine the order of deployment. This means that TestContract will be deployed first, which is what we want.

Now, let us look at constructorArgs. TestContract's dictionary specifies the exact name of the constructor argument (e.g. _x or _y) with their associated value. Since _z is of type TestContract.Abc, _z is also a dictionary that specifies each field in the TestContract.Abc struct.

For DependentOnTestContract, the _deployed key has a value of DeployedContract:TestContract. This tells medusa to look for a deployed contract that has the nameTestContract and provide its address as the value for _deployed. Thus, whenever you need a deployed contract's address as an argument for another contract, you must follow the format DeployedContract:<ContractName>.