fuzzland / ityfuzz

Blazing Fast Bytecode-Level Hybrid Fuzzer for Smart Contracts
https://docs.ityfuzz.rs
MIT License
735 stars 116 forks source link

Fuzz with foundry custom setup is not targeting all the targetContracts #466

Closed albertolalanda closed 2 months ago

albertolalanda commented 2 months ago

Hi, i am trying some onchain fuzzing with a custom test, and I think ityfuzz is not working as intended. My goal is to use ityFuzz to see if this Platypus exploit could have been found.

One of the contracts to fuzz, PlatypusPool = 0x4658EA7e9960D6158a261104aAA160cC953bb6ba is not getting fuzzed for some reason. However if i run it with ityfuzz evm -t 0x4658EA7e9960D6158a261104aAA160cC953bb6ba,0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7 -f -c AVALANCHE --onchain-block-number 36346397 --onchain-etherscan-api-key <SNOWTRACE_API_KEY> the contract gets targeted and the correct functions are called, like swap().

Here is the test, I am running it with ityfuzz evm -m OnchainTest -k <SNOWTRACE_API_KEY> -- forge build

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.23;

import {Test} from "forge-std/Test.sol";
import {console} from "forge-std/console.sol";

interface IERC20 {
    function approve(address spender, uint256 value) external returns (bool);
    function transfer(address to, uint256 value) external returns (bool);
    function transferFrom(address from, address to, uint256 value) external returns (bool);
    function withdraw(uint256 wad) external;
    function deposit(uint256 wad) external returns (bool);
}

// ityfuzz evm -m OnchainTest -k <ETHERSCAN_API_KEY> -- forge build
// ityfuzz evm -t 0x4658EA7e9960D6158a261104aAA160cC953bb6ba,0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7 -f -c AVALANCHE --onchain-block-number 36346397 --onchain-etherscan-api-key <ETHERSCAN_API_KEY>

contract OnchainTest is Test {
    address WAVAX = 0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7;
    address SAVAX = 0x2b2C81e08f1Af8835a78Bb2A90AE924ACE0eA4bE;
    address PlatypusPool = 0x4658EA7e9960D6158a261104aAA160cC953bb6ba;

    uint256 oldBalance;

    address caller;

    function setUp() public {
        vm.createSelectFork("https://rpc.ankr.com/avalanche", 36_346_397);

        targetContract(WAVAX);
        targetContract(PlatypusPool);

        vm.deal(address(this), 2000000 ether);

        oldBalance = address(this).balance;

        IERC20(WAVAX).approve(PlatypusPool, type(uint256).max);
        IERC20(SAVAX).approve(PlatypusPool, type(uint256).max);
    }

    function invariant_1() public {
        assertLe(address(this).balance, oldBalance);
    }
}
jacob-chia commented 2 months ago

The command ityfuzz evm -m OnchainTest -k <SNOWTRACE_API_KEY> -- forge build conducts Offchain tests, requiring the target contracts to be local. Here's a quick rundown of how this command operates:

  1. -k <SNOWTRACE_API_KEY> is optional, only necessary when Onchain flashloans are involved.
  2. forge build is used to compile the targets, producing offchain_artifacts.
  3. ityfuzz picks up the offchain_artifacts and deploys them on the local evm.
  4. Start fuzzing.

Check out this example for reference: https://github.com/fuzzland/ityfuzz/blob/master/tests/evm_manual/foundry1/test/Counter.t.sol

albertolalanda commented 2 months ago

I was trying to replicate how it was done for the StaxExploit test.

So what command would I use to fuzz onchain, if possible?

shouc commented 2 months ago

Shall be fixed with #469

albertolalanda commented 2 months ago

After #469 ittyfuzz now picks up the target contracts abi and fuzzes as intended. Thank you @shouc