GithubHelp home page GithubHelp logo

fuzzland / ityfuzz Goto Github PK

View Code? Open in Web Editor NEW
610.0 10.0 89.0 4.44 MB

Blazing Fast Bytecode-Level Hybrid Fuzzer for Smart Contracts

Home Page: https://docs.ityfuzz.rs

License: MIT License

Rust 92.37% Solidity 4.22% Python 1.73% Dockerfile 0.07% Shell 0.75% HTML 0.03% JavaScript 0.09% Move 0.47% Handlebars 0.27%
concolic-execution fuzzing smart-contracts aptos evm move sui ethereum solidity blockchain

ityfuzz's Introduction

🍦 ItyFuzz

Demo

[Docs] / [Research Paper] / [Twitter] / [Discord] / [Telegram]

ItyFuzz is a blazing-fast EVM and MoveVM smart contract hybrid fuzzer that combines symbolic execution and fuzzing to find bugs in smart contracts offchain and onchain.

Install

curl -L https://ity.fuzz.land/ | bash
ityfuzzup

Example

Fuzzing Deployed Smart Contract

Generating full exploit to steal funds from a contract with flashloan + read-only reentrancy vulnerability on Polygon.

# Fork Polygon at block 35718198 and fuzz the contract
ETH_RPC_URL=https://polygon-rpc.com ityfuzz evm\
    -t 0xbcf6e9d27bf95f3f5eddb93c38656d684317d5b4,0x5d6c48f05ad0fde3f64bab50628637d73b1eb0bb\
    -c polygon\
    --flashloan\
    --onchain-block-number 35718198\
    --onchain-etherscan-api-key TR24XDQF35QCNK9PZBV8XEH2XRSWTPWFWT # <-- Get your own API key at https://polygonscan.com/apis if this one is rate limited 

Foundry Invariant Test

Run a Foundry invariant test defined in Invariant contract in test/Invariant.sol.

# Replaces: forge test --mc test/Invariant.sol:Invariant
ityfuzz evm -m test/Invariant.sol:Invariant -- forge test

For other examples and usages, check out the docs.

Performance

On large real-world smart contract projects, ItyFuzz finds 126 vulnerabilities while Echidna finds 0 and Mythril finds 9. For details, refer to backtesting, research paper, and new bugs discovered.

On small real-world smart contracts (ERC20, lottery, etc.), ItyFuzz gains 10% more test coverage than academia state-of-the-art fuzzer SMARTIAN using 1/30 of the time.

On Consensys's Daedaluzz benchmark, ItyFuzz without symbolic execution finds 44% more bugs than Echidna and 31% more bugs than Foundry. ItyFuzz is also 2.5x faster than Echidna and 1.5x faster than Foundry.

Features

  • Chain forking to fuzz contracts on any chain at any block number.
  • Accurate exploit generation for precision loss, integer overflow, fund stealing, Uniswap pair misuse etc.
  • Reentrancy support to concretely leverage potential reentrancy opportunities for exploring more code paths.
  • Blazing fast power scheduling to prioritize fuzzing on code that is more likely to have bugs.
  • Symbolic execution to generate test cases that cover more code paths than fuzzing alone.
  • Flashloan support assuming attackers have infinite funds to exploit flashloan vulnerabilities.
  • Liquidation support to simulate buying and selling any token from liquidity pools during fuzzing.
  • Decompilation support for fuzzing contracts without source code.
  • Supports complex contracts initialization using Foundry setup script, forking Anvil RPC, or providing a JSON config file.
  • Backed by SOTA Web2 fuzzing engine LibAFL.

Bugs Found

Selected new vulnerabilities found:

Project Vulnerability Assets at Risks
BSC $rats NFT Integer overflow leading to unlimited minting $79k
9419 Token Incorrect logic leading to price manipulation $35k
BSC Mevbot Unguarded DPPFlashLoanCall $19k
FreeCash Incorrect logic leading to price manipulation $12k
0xnoob Token Incorrect logic leading to price manipulation $7k
Baby Wojak Token Incorrect logic leading to price manipulation $4k
Arrow Incorrect position logic leading to fund loss Found During Audit

ItyFuzz can automatically generate exploits for >80% of previous hacks without any knowledge of the hack. Refer to backtesting for running previously hacked protocols.

Sponsors & Grants

ityfuzz's People

Contributors

0xawm avatar 0xhtt avatar 0xxfu avatar bytesecurity avatar cloud10240 avatar davidberiro avatar engn33r avatar faculerena avatar ivoider avatar jacob-chia avatar jf-li00 avatar kenun99 avatar mingxiye avatar omahs avatar publicqi avatar shangyint avatar shouc avatar stanfordreject avatar zhouxianyuan avatar zorrosword avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ityfuzz's Issues

[Need Fix]Is there any possible to change set the txn data from bytes to args (i.e., BoxedABI)?

I failed to update the txn data (ABI) in the EVMInput using the method set_bytes.

pub fn set_bytes(&mut self, bytes: Vec<u8>) {

It seems that the concolic engine also needs to update the abi data of the current input.

// .set_bytes(str_to_bytes(&s));

However, although I have activated the code after removing the annotations, fn set_bytes() still failed to change the input data.
I was wondering whether it is possible to let me ask for any suggestions?
Does the set_bytes in ABI work well?

The concrete example is shown here. The below code is inserted into the entry of fn evaluate_input_events in ityfuzz/src/fuzzer.rs. However, the two print commands output the sample.

tx_bytes = [0, 0, 0, 0] // example data
let mut cu_input = input.clone();
println!("got it: {:02x?}", cu_input.get_data_abi());
cu_input
    .get_data_abi_mut()
    .as_mut()
    .unwrap()
    .set_bytes(tx_bytes.to_vec());
println!("got it: {:02x?}", cu_input.get_data_abi());

https://fuzz.land/free !

Why does this problem appear?

./cli -o -t 0x10ED43C718714eb63d5aA57B78B54704E256024E,0xcFF086EaD392CcB39C49eCda8C974ad5238452aC --onchain-block-number 22055611 -c BSC --onchain-local-proxy-addr http://localhost:5003
thread 'main' panicked at 'called Result::unwrap() on an Err value: reqwest::Error { kind: Request, url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("fuzz.land")), port: None, path: "/free", query: None, fragment: None }, source: hyper::Error(Connect, ConnectError("dns error", Custom { kind: Uncategorized, error: "failed to lookup address information: Temporary failure in name resolution" })) }', src/licensing.rs:30:64
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

Attack Types

Can you unpack the attack into different modules:

  • Reentrancy
  • Pool Issues
  • Arbitrary External Call
  • Rug Pull?
  • ...

time overflow

Environment:

Docker
fuzzland/ityfuzz:latest 9443aba6458d
on wsl

Have ran multiple smart contracts and all of them seem to crash at around 7 minutes with the following error:

thread 'main' panicked at 'overflow when subtracting durations', library/core/src/time.rs:936:31
stack backtrace:
   0: rust_begin_unwind
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/std/src/panicking.rs:577:5
   1: core::panicking::panic_fmt
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:67:14
   2: core::panicking::panic_display
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:150:5
   3: core::panicking::panic_str
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:134:5
   4: core::option::expect_failed
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/option.rs:2025:5
   5: core::option::Option<T>::expect
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/option.rs:913:21
   6: <core::time::Duration as core::ops::arith::Sub>::sub
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/time.rs:936:31
   7: <ityfuzz::fuzzer::ItyFuzzer<VS,Loc,Addr,Out,CS,IS,F,IF,I,OF,S,OT> as libafl::fuzzer::Fuzzer<E,EM,I,S,ST>>::fuzz_loop
   8: ityfuzz::fuzzers::evm_fuzzer::evm_fuzzer
   9: cli::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

thread 'main' panicked at 'arithmetic operation overflow'

thread 'main' panicked at 'arithmetic operation overflow', /home/rappie/.cargo/registry/src/index.crates.io-6f17d22bba15001f/primitive-types-0.12.1/src/lib.rs:38:1
stack backtrace:
   0: rust_begin_unwind
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/std/src/panicking.rs:577:5
   1: core::panicking::panic_fmt
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:67:14
   2: <primitive_types::U256 as core::ops::arith::Mul>::mul
   3: <ityfuzz::evm::oracles::erc20::IERC20OracleFlashloan as ityfuzz::oracle::Oracle<ityfuzz::evm::vm::EVMState,primitive_types::H160,revm::interpreter::bytecode::Bytecode,bytes::bytes::Bytes,primitive_types::H160,primitive_types::U256,alloc::vec::Vec<u8>,ityfuzz::evm::input::EVMInput,ityfuzz::state::FuzzState<ityfuzz::evm::input::EVMInput,ityfuzz::evm::vm::EVMState,primitive_types::H160,primitive_types::H160,alloc::vec::Vec<u8>>>>::oracle
   4: <ityfuzz::feedback::OracleFeedback<VS,Addr,Code,By,Loc,SlotTy,Out,I,S> as libafl::feedbacks::Feedback<I,S>>::is_interesting
   5: <ityfuzz::fuzzer::ItyFuzzer<VS,Loc,Addr,Out,CS,IS,F,IF,I,OF,S,OT> as libafl::fuzzer::Evaluator<E,EM,I,S>>::evaluate_input_events
   6: <(Head,Tail) as libafl::stages::StagesTuple<E,EM,S,Z>>::perform_all
   7: <(Head,Tail) as libafl::stages::StagesTuple<E,EM,S,Z>>::perform_all
   8: <ityfuzz::fuzzer::ItyFuzzer<VS,Loc,Addr,Out,CS,IS,F,IF,I,OF,S,OT> as libafl::fuzzer::Fuzzer<E,EM,I,S,ST>>::fuzz_loop
   9: ityfuzz::fuzzers::evm_fuzzer::evm_fuzzer
  10: cli::main

False Positive due to Broken Tracer

There seems to be some FP caused by tracer. Although the fuzzer managed to find an exploitable bug, but the transactions generated is broken

Error 'already borrowed: BorrowMutError'

Using latest cli version

thread 'main' panicked at 'already borrowed: BorrowMutError', /home/rappie/Desktop/repos/ityfuzz.git/src/evm/host.rs:308:78
stack backtrace:
   0: rust_begin_unwind
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/std/src/panicking.rs:577:5
   1: core::panicking::panic_fmt
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:67:14
   2: core::result::unwrap_failed
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/result.rs:1687:5
   3: ityfuzz::evm::host::FuzzHost<VS,I,S>::set_code
   4: <ityfuzz::evm::onchain::onchain::OnChain<VS,I,S> as ityfuzz::evm::middlewares::middleware::Middleware<VS,I,S>>::on_step
   5: <ityfuzz::evm::host::FuzzHost<VS,I,S> as revm::evm_impl::Host<S>>::step
   6: revm::interpreter::Interpreter::run
   7: ityfuzz::evm::vm::EVMExecutor<I,S,VS>::execute_from_pc
   8: <ityfuzz::evm::vm::EVMExecutor<I,S,VS> as ityfuzz::generic_vm::vm_executor::GenericVM<VS,revm::interpreter::bytecode::Bytecode,bytes::bytes::Bytes,primitive_types::H160,primitive_types::H160,primitive_types::U256,alloc::vec::Vec<u8>,I,S>>::execute
   9: <ityfuzz::executor::FuzzExecutor<VS,Addr,Code,By,Loc,SlotTy,Out,I,S,OT> as libafl::executors::Executor<EM,I,S,Z>>::run_target
  10: <(Head,Tail) as libafl::stages::StagesTuple<E,EM,S,Z>>::perform_all
  11: <ityfuzz::fuzzer::ItyFuzzer<VS,Loc,Addr,Out,CS,IS,F,IF,I,OF,S,OT> as libafl::fuzzer::Fuzzer<E,EM,I,S,ST>>::fuzz_loop
  12: ityfuzz::fuzzers::evm_fuzzer::evm_fuzzer
  13: cli::main

Bug oracle is not unique enough

For some reason it triggered (even without --bug-oracle) for the following contract:

/ityfuzz/cli/target/release/cli -c ETH --onchain --onchain-block-number 17521638 -f --target 0xa5564a2d1190a141cac438c9fde686ac48a18a79

😊😊 Found violations! 


================ Oracle ================
[bug] bug() hit at contract 0x5b19bd330a84c049b62d5b0fc2ba120217a18c1c

================ Trace ================
Begin
{"caller":"0x68dd4f5ac792eaaa5e36f4f4e0474e0625dc9024","contract":"0xd96f48665a1410c0cd669a88898eca36b9fc2cce","data":"harvest(0x38ea452219524bb87e18de1c24d3bb59510bd783,0x00,0x000000001a000000000000000000000000000000000000000000000000004d4d) with None ETH (66c6bb0b00000000000000000000000038ea452219524bb87e18de1c24d3bb59510bd7830000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000004d4d)","value":null,"flashloan":"earned: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512, owed: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512","direct_data":[],"layer":0,"additional_info":[1]}

 == {"caller":"0x8ef508aca04b32ff3ba5003177cb18bfa6cd79dd","contract":"0xaf5191b0de278c7286d6c7cc6ab6bb8a73ba2cd6","data":"transfer(0x8439ac976ac597c71c0512d8a53697a39e8f9773,0x0000000000000000000000000000000000000000000000000000000000000000) with None ETH (a9059cbb0000000000000000000000008439ac976ac597c71c0512d8a53697a39e8f97730000000000000000000000000000000000000000000000000000000000000000)","value":null,"flashloan":"earned: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512, owed: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512","direct_data":[],"layer":1,"additional_info":[255]}

 == {"caller":"0x8ef508aca04b32ff3ba5003177cb18bfa6cd79dd","contract":"0x101816545f6bd2b1076434b54383a1e633390a2e","data":"Stepping with return: 307830303030303030303030303030303030303030303030303030303030303030303030303030303030303065643030303030303030303030303030303033343064 with None ETH (00000000000000000000000000000000000000000000000000ed0000000000000000340d)","value":null,"flashloan":"earned: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512, owed: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512","direct_data":[],"layer":1,"additional_info":[255]}

{"caller":"0x35c9dfd76bf02107ff4f7128bd69716612d31ddb","contract":"0x4d73adb72bc3dd368966edd0f0b2148401a178e2","data":"withdrawNative(0xcc0d7af1f809dd3a589756bba36be04d19e9c6c5,0x0000000000000000000000000000000000000000000000000000000000000000) with None ETH (07b18bde000000000000000000000000cc0d7af1f809dd3a589756bba36be04d19e9c6c50000000000000000000000000000000000000000000000000000000000000000)","value":null,"flashloan":"earned: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512, owed: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512","direct_data":[],"layer":0,"additional_info":[1]}

 == {"caller":"0x35c9dfd76bf02107ff4f7128bd69716612d31ddb","contract":"0x4d73adb72bc3dd368966edd0f0b2148401a178e2","data":"Stepping with return:  with Some(0x000000000000000000000000000000000000fb8000000000006c000000000000_U256) ETH (00000000)","value":"0x000000000000000000000000000000000000fb8000000000006c000000000000","flashloan":"earned: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512, owed: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512","direct_data":[],"layer":1,"additional_info":[255]}

{"caller":"0x8ef508aca04b32ff3ba5003177cb18bfa6cd79dd","contract":"0x5b19bd330a84c049b62d5b0fc2ba120217a18c1c","data":"updateHash(0x406f,0x,0x0000000001000018001ff300000000000b0b0b0b0b0b0b0b0b6f800000003055,0x) with None ETH (704316e5000000000000000000000000000000000000000000000000000000000000406f00000000000000000000000000000000000000000000000000000000000000800000000001000018001ff300000000000b0b0b0b0b0b0b0b0b6f80000000305500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)","value":null,"flashloan":"earned: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512, owed: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512","direct_data":[],"layer":0,"additional_info":[255]}

{"caller":"0x8ef508aca04b32ff3ba5003177cb18bfa6cd79dd","contract":"0x5b19bd330a84c049b62d5b0fc2ba120217a18c1c","data":"updateHash(0x0000,0x,0xff00ffffffffffffffffffffffb2b2b2b2b2b2b2b2ffffff0000000000000000,0x) with None ETH (704316e500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080ff00ffffffffffffffffffffffb2b2b2b2b2b2b2b2ffffff000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)","value":null,"flashloan":"earned: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512, owed: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512","direct_data":[],"layer":0,"additional_info":[255]}

{"caller":"0xe1a425f1ac34a8a441566f93c82dd730639c8510","contract":"0x5b19bd330a84c049b62d5b0fc2ba120217a18c1c","data":"withdrawNative(0x01,0x06d538690af257da524f25d0cd52fd85b1c2173e,0xd8772edbf88bba2667ed011542343b0eddacda47,0x0000000000000000000000000000000000000000000000000000000000000000) with None ETH (22c10776000000000000000000000000000000000000000000000000000000000000000100000000000000000000000006d538690af257da524f25d0cd52fd85b1c2173e000000000000000000000000d8772edbf88bba2667ed011542343b0eddacda470000000000000000000000000000000000000000000000000000000000000000)","value":null,"flashloan":"earned: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512, owed: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512","direct_data":[],"layer":0,"additional_info":[1]}

 == {"caller":"0xe1a425f1ac34a8a441566f93c82dd730639c8510","contract":"0x5b19bd330a84c049b62d5b0fc2ba120217a18c1c","data":"Stepping with return:  with Some(0x0000000000000000000000000000000000000000000000000000000000000000_U256) ETH (00000000)","value":"0x0000000000000000000000000000000000000000000000000000000000000000","flashloan":"earned: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512, owed: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_U512","direct_data":[],"layer":1,"additional_info":[255]}

Feature: Better Liquidation Support

Currently, for EVM program fuzzing, we use Uniswap V2 / Pancakeswap for borrowing flash loan. Specifically, we provide hacker ETHs and swap these ETHs into the desired token using Uniswap router during flash loan phase, and swap it back to ETHs during the liquidation phase. However, the majority of tokens have migrated to Uniswap V3. We want to support both V2/V3 during flashloan and liquidation, and here are the actionable items:

  • Build a quotation algorithm that is provided with (an array of paths with their reserves information, # of desired token expected to receive) and returns an array of (path, percentage). Similar to 1inch's quote API but we need to have high performance.
  • Instead of using Uniswap router, directly calculate the amountOut for each hop in the swap path and use it to build a sequence of transactions (e.g., transfer(token1) -> swap(token1, token2) -> transfer(token2) -> swap(token2, token3))
  • Index all pairs for Uniswap V3, Uniswap V2, Sushiswap, Pancakeswap, etc. so that the quotation algorithm can be initialized in short time

Foundry & Hardhat Support

We should support foundry and hardhat projects:

  • Create our own RPC endpoint for deployment -> address, bytecode, storage
  • Fork the destination chain

thread 'main' panicked at 'range end index 36 out of range for slice of length 4'

./cli -o --onchain-block-number 0 --chain-type ETH --onchain-local-proxy-addr http://127.0.0.1:5003 --panic-on-bug --flashloan --concolic --ierc20-oracle --pair-oracle --target 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D,0x3c4fe0db16c9b521480c43856ba3196a9fa50e08
thread 'main' panicked at 'range end index 36 out of range for slice of length 4', /home/rappie/Desktop/ityfuzz.git/src/evm/onchain/flashloan.rs:510:53
stack backtrace:
   0: rust_begin_unwind
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/std/src/panicking.rs:577:5
   1: core::panicking::panic_fmt
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:67:14
   2: core::slice::index::slice_end_index_len_fail_rt
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/slice/index.rs:78:5
   3: core::slice::index::slice_end_index_len_fail
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/slice/index.rs:70:9
   4: <ityfuzz::evm::host::FuzzHost<VS,I,S> as revm::evm_impl::Host<S>>::step
   5: revm::interpreter::Interpreter::run
   6: ityfuzz::evm::vm::EVMExecutor<I,S,VS>::execute_from_pc
   7: <ityfuzz::evm::vm::EVMExecutor<I,S,VS> as ityfuzz::generic_vm::vm_executor::GenericVM<VS,revm::interpreter::bytecode::Bytecode,bytes::bytes::Bytes,primitive_types::H160,primitive_types::H160,primitive_types::U256,alloc::vec::Vec<u8>,I,S>>::execute
   8: <ityfuzz::executor::FuzzExecutor<VS,Addr,Code,By,Loc,SlotTy,Out,I,S,OT> as libafl::executors::Executor<EM,I,S,Z>>::run_target
   9: <(Head,Tail) as libafl::stages::StagesTuple<E,EM,S,Z>>::perform_all
  10: <ityfuzz::fuzzer::ItyFuzzer<VS,Loc,Addr,Out,CS,IS,F,IF,I,OF,S,OT> as libafl::fuzzer::Fuzzer<E,EM,I,S,ST>>::fuzz_loop
  11: ityfuzz::fuzzers::evm_fuzzer::evm_fuzzer
  12: cli::main

thread 'main' panicked at 'failed to parse abi file: Error("expected value", line: 1, column: 1)'

I keep getting this error. Maybe it's because of rate limiting?

fetching abi from https://api.bscscan.com/api/?module=contract&action=getabi&address=0x0feadcc3824e7f3c12f40e324a60c23ca51627fc&format=json&apikey=<redacted>
thread 'main' panicked at 'failed to parse abi file: Error("expected value", line: 1, column: 1)', /home/rappie/ityfuzz.git/src/evm/contract_utils.rs:87:60
stack backtrace:
   0: rust_begin_unwind
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/std/src/panicking.rs:577:5
   1: core::panicking::panic_fmt
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:67:14
   2: core::result::unwrap_failed
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/result.rs:1687:5
   3: ityfuzz::evm::contract_utils::ContractLoader::parse_abi_str
   4: <ityfuzz::evm::onchain::onchain::OnChain<VS,I,S> as ityfuzz::evm::middleware::Middleware<VS,I,S>>::on_step
   5: <ityfuzz::evm::host::FuzzHost<VS,I,S> as revm::evm_impl::Host<S>>::step
   6: revm::interpreter::Interpreter::run
   7: <ityfuzz::evm::host::FuzzHost<VS,I,S> as revm::evm_impl::Host<S>>::call
   8: revm::instructions::host::call
   9: revm::interpreter::Interpreter::run
  10: ityfuzz::evm::vm::EVMExecutor<I,S,VS>::execute_from_pc
  11: <ityfuzz::evm::vm::EVMExecutor<I,S,VS> as ityfuzz::generic_vm::vm_executor::GenericVM<VS,revm::interpreter::bytecode::Bytecode,bytes::bytes::Bytes,primitive_types::H160,primitive_types::H160,primitive_types::U256,alloc::vec::Vec<u8>,I,S>>::execute
  12: <ityfuzz::executor::FuzzExecutor<VS,Addr,Code,By,Loc,SlotTy,Out,I,S,OT> as libafl::executors::Executor<EM,I,S,Z>>::run_target
  13: <(Head,Tail) as libafl::stages::StagesTuple<E,EM,S,Z>>::perform_all
  14: <ityfuzz::fuzzer::ItyFuzzer<VS,Loc,Addr,Out,CS,IS,F,IF,I,OF,S,OT> as libafl::fuzzer::Fuzzer<E,EM,I,S,ST>>::fuzz_loop
  15: ityfuzz::fuzzers::evm_fuzzer::evm_fuzzer
  16: cli::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Trouble reproducing solution

I'm having trouble reproducing a solution in Tenderly and Foundy. I'm not sure how to read the flashloan trace exactly.

Could there be a bug where the flashloan logic sends eth through msg.value to a non-payable function? This would explain things as a false positive.

The target contract is a live contract so I cannot share it publicly here. Maybe we can talk in private? You can reach me on Discord, Rappie#6502 (Immunefi server among others). If Discord is not an option you can also reach me on twitter @rappenstein2. Thanks.

Panic If `balanceOf` Reverts During Flashloan

thread 'main' panicked at 'assertion failed: 4 * 8 >= slice.len()', /home/h/开发/rust/.cargo/registry/src/index.crates.io-6f17d22bba15001f/primitive-types-0.12.1/src/lib.rs:38:1
stack backtrace:
   0: rust_begin_unwind
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/std/src/panicking.rs:577:5
   1: core::panicking::panic_fmt
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:67:14
   2: core::panicking::panic
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:117:5
   3: <primitive_types::U256 as core::convert::From<&[u8]>>::from
   4: <ityfuzz::evm::oracle::IERC20OracleFlashloan as ityfuzz::oracle::Oracle<ityfuzz::evm::vm::EVMState,primitive_types::H160,revm::interpreter::bytecode::Bytecode,bytes::bytes::Bytes,primitive_types::H160,primitive_types::U256,alloc::vec::Vec<u8>,ityfuzz::evm::input::EVMInput,ityfuzz::state::FuzzState<ityfuzz::evm::input::EVMInput,ityfuzz::evm::vm::EVMState,primitive_types::H160,primitive_types::H160,alloc::vec::Vec<u8>>>>::oracle
   5: <ityfuzz::feedback::OracleFeedback<VS,Addr,Code,By,Loc,SlotTy,Out,I,S> as libafl::feedbacks::Feedback<I,S>>::is_interesting
   6: <ityfuzz::fuzzer::ItyFuzzer<VS,Loc,Addr,Out,CS,IS,F,IF,I,OF,S,OT> as libafl::fuzzer::Evaluator<E,EM,I,S>>::evaluate_input_events
   7: <(Head,Tail) as libafl::stages::StagesTuple<E,EM,S,Z>>::perform_all
   8: <(Head,Tail) as libafl::stages::StagesTuple<E,EM,S,Z>>::perform_all
   9: <ityfuzz::fuzzer::ItyFuzzer<VS,Loc,Addr,Out,CS,IS,F,IF,I,OF,S,OT> as libafl::fuzzer::Fuzzer<E,EM,I,S,ST>>::fuzz_loop
  10: ityfuzz::fuzzers::evm_fuzzer::evm_fuzzer
  11: cli::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Panic for Fuzzing on Ethereum in Docker Image

thread 'main' panicked at 'Invalid chain type', src/main.rs:135:29
stack backtrace:
   0: rust_begin_unwind
             at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/core/src/panicking.rs:142:14
   2: core::panicking::panic_display
             at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/core/src/panicking.rs:72:5
   3: core::panicking::panic_str
             at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/core/src/panicking.rs:56:5
   4: core::option::expect_failed
             at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/core/src/option.rs:1880:5
   5: cli::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

vm.rs:1167:13

I am encountering this issue with 90% of the results I have run on the Docker image

[Testcase #0] run time: 0h-1m-5s, clients: 1, corpus: 58, objectives: 0, executions: 893, exec/sec: 16
thread 'main' panicked at 'no code 0x10ed43c718714eb63d5aa57b78b54704e256024e', /build/src/evm/vm.rs:1167:13
stack backtrace:
0: rust_begin_unwind
at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/std/src/panicking.rs:584:5
1: core::panicking::panic_fmt
at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/core/src/panicking.rs:142:14
2: core::panicking::panic_display
at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/core/src/panicking.rs:72:5
3: core::panicking::panic_str
at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/core/src/panicking.rs:56:5
4: core::option::expect_failed
at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/core/src/option.rs:1880:5
5: <ityfuzz::evm::vm::EVMExecutor<I,S,VS> as ityfuzz::generic_vm::vm_executor::GenericVM<VS,revm::interpreter::bytecode::Bytecode,bytes::bytes::Bytes,primitive_types::H160,primitive_types::H160,primitive_types::U256,alloc::vec::Vec,I,S>>::execute
6: <ityfuzz::executor::FuzzExecutor<VS,Addr,Code,By,Loc,SlotTy,Out,I,S,OT> as libafl::executors::Executor<EM,I,S,Z>>::run_target
7: <(Head,Tail) as libafl::stages::StagesTuple<E,EM,S,Z>>::perform_all
8: <ityfuzz::fuzzer::ItyFuzzer<VS,Loc,Addr,Out,CS,IS,F,IF,I,OF,S,OT> as libafl::fuzzer::Fuzzer<E,EM,I,S,ST>>::fuzz_loop
9: ityfuzz::fuzzers::cmp_fuzzer::cmp_fuzzer
10: cli::main
note: Some details are omitted, run with RUST_BACKTRACE=full for a verbose backtrace.

host.rs:676:13

/cli -f -t "../../../tests/verilog-2/*

==========================================
[Testcase #0] run time: 0h-0m-0s, clients: 1, corpus: 41, objectives: 0, executions: 9304, exec/sec: 0
[Stats #0] run time: 0h-0m-0s, clients: 1, corpus: 41, objectives: 0, executions: 11203, exec/sec: 0
[Stats #0] run time: 0h-0m-0s, clients: 1, corpus: 41, objectives: 0, executions: 14012, exec/sec: 0
[Stats #0] run time: 0h-0m-0s, clients: 1, corpus: 41, objectives: 0, executions: 16602, exec/sec: 0
[Stats #0] run time: 0h-0m-0s, clients: 1, corpus: 41, objectives: 0, executions: 19155, exec/sec: 0
[Stats #0] run time: 0h-0m-0s, clients: 1, corpus: 41, objectives: 0, executions: 21789, exec/sec: 0
[Stats #0] run time: 0h-0m-0s, clients: 1, corpus: 41, objectives: 0, executions: 24588, exec/sec: 0
[Stats #0] run time: 0h-0m-1s, clients: 1, corpus: 41, objectives: 0, executions: 27245, exec/sec: 26797
thread 'main' panicked at 'target hit, "0000000000000000000000008ef508aca04b32ff3ba5003177cb18bfa6cd79dd" - [0x0000000000000000000000000000000000000000000000000000000000133337]', /home/ubuntu/Desktop/ityfuzz/src/evm/host.rs:676:13
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

Can't run the tool

In the installation guide for Linux, you mention the binaries and suggest running these commands:

# if cli binary exists
cd ./cli/
./cli -t '../tests/multi-contract/*'

Should they be created after the installation, or do I have to make them myself?

I appreciate any help you can provide.

Why reentrancy

Why is there reentrancy in skim() detected by the tool?

thread 'main' panicked at 'assertion failed: 4 * 8 >= slice.len()',

On BSC:

...

fetching abi 0x406ec2705f1399d25801bd86b7d8d69ab9a91ab9
constructor()
EMISSION()
LOCK()
MAX_TEAM_RATE()
PRECISION()
REBASEMAX()
TAIL_EMISSION()
WEEK()
_initialize(address[],uint256[],uint256)
_rewards_distributor()
_thena()
_ve()
_voter()
acceptTeam()
active_period()
calculate_emission()
calculate_rebate(uint256)
check()
circulating_emission()
circulating_supply()
initialize(address,address,address)
isFirstMint()
owner()
pendingTeam()
period()
renounceOwnership()
setEmission(uint256)
setRebase(uint256)
setRewardDistributor(address)
setTeam(address)
setTeamRate(uint256)
setVoter(address)
team()
teamRate()
transferOwnership(address)
update_period()
weekly()
weekly_emission()
Voted for 0
thread 'main' panicked at 'assertion failed: 4 * 8 >= slice.len()', /root/.cargo/registry/src/github.com-1ecc6299db9ec823/primitive-types-0.12.1/src/lib.rs:38:1
stack backtrace:
   0: rust_begin_unwind
             at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/core/src/panicking.rs:142:14
   2: core::panicking::panic
             at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/core/src/panicking.rs:48:5
   3: <primitive_types::U256 as core::convert::From<&[u8]>>::from
   4: <ityfuzz::evm::oracle::IERC20OracleFlashloan as ityfuzz::oracle::Oracle<ityfuzz::evm::vm::EVMState,primitive_types::H160,revm::interpreter::bytecode::Bytecode,bytes::bytes::Bytes,primitive_types::H160,primitive_types::U256,alloc::vec::Vec<u8>,ityfuzz::evm::input::EVMInput,ityfuzz::state::FuzzState<ityfuzz::evm::input::EVMInput,ityfuzz::evm::vm::EVMState,primitive_types::H160,primitive_types::H160,alloc::vec::Vec<u8>>>>::oracle
   5: <ityfuzz::feedback::OracleFeedback<VS,Addr,Code,By,Loc,SlotTy,Out,I,S> as libafl::feedbacks::Feedback<I,S>>::is_interesting
   6: <ityfuzz::fuzzer::ItyFuzzer<VS,Loc,Addr,Out,CS,IS,F,IF,I,OF,S,OT> as libafl::fuzzer::Evaluator<E,EM,I,S>>::evaluate_input_events
   7: <(Head,Tail) as libafl::stages::StagesTuple<E,EM,S,Z>>::perform_all
   8: <ityfuzz::fuzzer::ItyFuzzer<VS,Loc,Addr,Out,CS,IS,F,IF,I,OF,S,OT> as libafl::fuzzer::Fuzzer<E,EM,I,S,ST>>::fuzz_loop
   9: ityfuzz::fuzzers::cmp_fuzzer::cmp_fuzzer
  10: cli::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Crash when the blocknumber is not provided

It's supposed to use the latest block when no block number is provided.
image

Also the campaign does not end automatically when there is error. I have to cancel it myself to stop it running.

Unable to find burn exploit for SAFEMOON

Input: 0x42981d0bfbAf196529376EE702F2a9Eb9092fcB5,0x10ed43c718714eb63d5aa57b78b54704e256024e,0x87d7fd8c446cb5d3da3ca23f429e7b7504d1931c @ block 26854757

Reason:

  • SafeSwap is close-sourced, so unable to find ABI. Heimdall seems to be broken here :(
  • Cannot automatically use SafeSwap for liquidation

Proxy error: Exception on /swap_path/eth/.../latest

Let me know if you need more info

Traceback (most recent call last):
  File "/home/rappie/.pyenv/versions/ityfuzz/lib/python3.10/site-packages/flask/app.py", line 2529, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/rappie/.pyenv/versions/ityfuzz/lib/python3.10/site-packages/flask/app.py", line 1825, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/rappie/.pyenv/versions/ityfuzz/lib/python3.10/site-packages/flask/app.py", line 1823, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/rappie/.pyenv/versions/ityfuzz/lib/python3.10/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
  File "/home/rappie/Desktop/ityfuzz.git/proxy/main.py", line 621, in swap_path
    return flask.jsonify(find_path_subgraph(network, token_address.lower(), block))
  File "/home/rappie/Desktop/ityfuzz.git/proxy/main.py", line 371, in find_path_subgraph
    hops = get_all_hops(token, network, block, known=set())
  File "/home/rappie/Desktop/ityfuzz.git/proxy/main.py", line 322, in get_all_hops
    hops[token] = get_pair(token, network, block)
  File "/home/rappie/.pyenv/versions/ityfuzz/lib/python3.10/site-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
  File "/home/rappie/.pyenv/versions/ityfuzz/lib/python3.10/site-packages/retry/api.py", line 73, in retry_decorator
    return __retry_internal(partial(f, *args, **kwargs), exceptions, tries, delay, max_delay, backoff, jitter,
  File "/home/rappie/.pyenv/versions/ityfuzz/lib/python3.10/site-packages/retry/api.py", line 33, in __retry_internal
    return f()
  File "/home/rappie/Desktop/ityfuzz.git/proxy/main.py", line 266, in get_pair
    res = res["data"]
KeyError: 'data'

`Result::unwrap()` on an `Err` value: OddLength' at evm/onchain/endpoints.rs:513:38

Using latest code

Cmd: ./target/release/cli -o -i -t 0xBcF6e9d27bf95F3F5eDDB93C38656D684317D5b4 -c POLYGON --onchain-block-number 35690977 -f --onchain-local-proxy-addr http://xxxxxxx:5003 --onchain-storage-fetching onebyone --flashloan-price-oracle onchain

Error:
thread 'main' panicked at 'called Result::unwrap() on an Err value: OddLength', /root/xx/ityfuzz/src/evm/onchain/endpoints.rs:513:38
stack backtrace:
0: rust_begin_unwind
at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/std/src/panicking.rs:577:5
1: core::panicking::panic_fmt
at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:67:14
2: core::result::unwrap_failed
at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/result.rs:1687:5
3: ityfuzz::evm::onchain::endpoints::OnChainConfig::get_contract_code
4: <ityfuzz::evm::onchain::onchain::OnChain<VS,I,S> as ityfuzz::evm::middlewares::middleware::Middleware<VS,I,S>>::on_step
5: <ityfuzz::evm::host::FuzzHost<VS,I,S> as revm::evm_impl::Host>::step
6: revm::interpreter::Interpreter::run
7: ityfuzz::evm::vm::EVMExecutor<I,S,VS>::execute_from_pc
8: <ityfuzz::evm::vm::EVMExecutor<I,S,VS> as ityfuzz::generic_vm::vm_executor::GenericVM<VS,revm::interpreter::bytecode::Bytecode,bytes::bytes::Bytes,primitive_types::H160,primitive_types::H160,primitive_types::U256,alloc::vec::Vec,I,S>>::execute
9: <ityfuzz::executor::FuzzExecutor<VS,Addr,Code,By,Loc,SlotTy,Out,I,S,OT> as libafl::executors::Executor<EM,I,S,Z>>::run_target
10: <(Head,Tail) as libafl::stages::StagesTuple<E,EM,S,Z>>::perform_all
11: <ityfuzz::fuzzer::ItyFuzzer<VS,Loc,Addr,Out,CS,IS,F,IF,I,OF,S,OT> as libafl::fuzzer::Fuzzer<E,EM,I,S,ST>>::fuzz_loop
12: ityfuzz::fuzzers::evm_fuzzer::evm_fuzzer
13: cli::main

Crash

thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 0', /root/ityfuzz2/src/evm/uniswap/mod.rs:283:12
stack backtrace:
0: rust_begin_unwind
at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/std/src/panicking.rs:577:5
1: core::panicking::panic_fmt
at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:67:14
2: core::panicking::panic_bounds_check
at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:162:5
3: ityfuzz::evm::uniswap::generate_uniswap_router_call
4: <ityfuzz::evm::vm::EVMExecutor<I,S,VS> as ityfuzz::generic_vm::vm_executor::GenericVM<VS,revm::interpreter::bytecode::Bytecode,bytes::bytes::Bytes,primitive_types::H160,primitive_types::H160,primitive_types::U256,alloc::vec::Vec,I,S>>::execute
5: <ityfuzz::executor::FuzzExecutor<VS,Addr,Code,By,Loc,SlotTy,Out,I,S,OT> as libafl::executors::Executor<EM,I,S,Z>>::run_target
6: <ityfuzz::fuzzer::ItyFuzzer<VS,Loc,Addr,Out,CS,IS,F,IF,I,OF,S,OT> as libafl::fuzzer::Fuzzer<E,EM,I,S,ST>>::fuzz_loop
7: ityfuzz::fuzzers::evm_fuzzer::evm_fuzzer
8: cli::main
note: Some details are omitted, run with RUST_BACKTRACE=full for a verbose backtrace.

Question: Going from ItyFuzz finding to complete PoC

I've been looking at some old hacks and how they are found by ItyFuzz. I've noticed that the findings are often in the right direction but don't describe the full exploit.

For example, the Carrot hack output i'm getting is.

Oracle: 💰[Flashloan] Earned 115792089237316195423570985008687907853269984665640564039457584007913129639935000000 more than owed 148133967134024642964942186048715434943000000, net earned = 115792089237316195423570985008687907853121850698506539396492641821864414204992000000wei (115792089237316195423570985008687907853121850698506539396492ETH)
Found a solution! trace: Begin
{"caller":"0x35c9dfd76bf02107ff4f7128bd69716612d31ddb","contract":"0xcff086ead392ccb39c49ecda8c974ad5238452ac","data":"Borrow with Some(120968139825468103452524544) ETH, liq percent: 0","value":"0x6410000000fdff00000000","flashloan":"earned: 0, owed: 120968139825468103452524544000000","layer":0,"additional_info":[0]}

{"caller":"0x35c9dfd76bf02107ff4f7128bd69716612d31ddb","contract":"0xcff086ead392ccb39c49ecda8c974ad5238452ac","data":"Borrow with Some(148122912659567912990383767717842783716) ETH, liq percent: 0","value":"0x6f6f6f6f6f0000fffffff00000000de4","flashloan":"earned: 0, owed: 148122912659688881130209235821295308260000000","layer":0,"additional_info":[0]}

{"caller":"0x35c9dfd76bf02107ff4f7128bd69716612d31ddb","contract":"0xcff086ead392ccb39c49ecda8c974ad5238452ac","data":"Borrow with Some(11054474335686276869224313096707547) ETH, liq percent: 0","value":"0x22107150471d7bd69716613d31ddb","flashloan":"earned: 0, owed: 148133967134024567407078460134392015807000000","layer":0,"additional_info":[90]}

{"caller":"0x35c9dfd76bf02107ff4f7128bd69716612d31ddb","contract":"0xcff086ead392ccb39c49ecda8c974ad5238452ac","data":"Borrow with Some(75557863725914323419136) ETH, liq percent: 0","value":"0x10000000000000000000","flashloan":"earned: 0, owed: 148133967134024642964942186048715434943000000","layer":0,"additional_info":[51]}

{"caller":"0x35c9dfd76bf02107ff4f7128bd69716612d31ddb","contract":"0xcff086ead392ccb39c49ecda8c974ad5238452ac","data":"transReward(0x0f0110e1000404010a80001015010036045d0160) with None ETH (bb7bf89f000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000140f0110e1000404010a80001015010036045d0160000000000000000000000000), liq percent: 0","value":null,"flashloan":"earned: 115792089237316195423570985008687907853269984665640564039457584007913129639935000000, owed: 148133967134024642964942186048715434943000000","layer":0,"additional_info":[255]}

The transReward function is one of the main parts of the hack. But there are more actions (and thought processes) necessary to find the real exploit:

  • The right payload to pass to transReward
  • The transferFrom call to extract the tokens

This is from:
https://github.com/SunWeb3Sec/DeFiHackLabs/blob/2e02134be123f8bbaa3bbe5a40a9b5b0726dd637/src/test/Carrot_exp.sol

Carrot.transReward( hex"bf699b4b000000000000000000000000b4c79daB8f259C7Aee6E5b2Aa729821864227e84" );

Carrot.transferFrom(
	0x00B433800970286CF08F34C96cf07f35412F1161,
	address(this),
	310344736073087429864760
);

What is your workflow / are your suggestions on how to go from a raw finding to an actual PoC? Am I missing certain options available to get a more detailed trace? Any help would be greatly appreciated 🙂

B1 and B2 datasets

The readme mentions B1 and B2 datasets. But I couldn't find the list of contracts comprising these datasets anywhere. Is that list maintained somewhere else?

Panic When Fuzzing Contracts with DELETGATECALL

thread 'main' panicked at 'already borrowed: BorrowMutError', /root/fuzzing/ityfuzz/src/evm/onchain/flashloan.rs:232:60
stack backtrace:
   0: rust_begin_unwind
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/std/src/panicking.rs:577:5
   1: core::panicking::panic_fmt
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:67:14
   2: core::result::unwrap_failed
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/result.rs:1687:5
   3: ityfuzz::evm::onchain::flashloan::Flashloan<VS,I,S>::on_contract_insertion
   4: <ityfuzz::evm::onchain::onchain::OnChain<VS,I,S> as ityfuzz::evm::middleware::Middleware<VS,I,S>>::on_step
   5: <ityfuzz::evm::host::FuzzHost<VS,I,S> as revm::evm_impl::Host<S>>::step
   6: revm::interpreter::Interpreter::run
   7: <ityfuzz::evm::vm::EVMExecutor<I,S,VS> as ityfuzz::generic_vm::vm_executor::GenericVM<VS,revm::interpreter::bytecode::Bytecode,bytes::bytes::Bytes,primitive_types::H160,primitive_types::H160,primitive_types::U256,alloc::vec::Vec<u8>,I,S>>::fast_static_call
   8: <ityfuzz::evm::oracle::IERC20OracleFlashloan as ityfuzz::oracle::Oracle<ityfuzz::evm::vm::EVMState,primitive_types::H160,revm::interpreter::bytecode::Bytecode,bytes::bytes::Bytes,primitive_types::H160,primitive_types::U256,alloc::vec::Vec<u8>,ityfuzz::evm::input::EVMInput,ityfuzz::state::FuzzState<ityfuzz::evm::input::EVMInput,ityfuzz::evm::vm::EVMState,primitive_types::H160,primitive_types::H160,alloc::vec::Vec<u8>>>>::oracle
   9: <ityfuzz::feedback::OracleFeedback<VS,Addr,Code,By,Loc,SlotTy,Out,I,S> as libafl::feedbacks::Feedback<I,S>>::is_interesting
  10: <ityfuzz::fuzzer::ItyFuzzer<VS,Loc,Addr,Out,CS,IS,F,IF,I,OF,S,OT> as libafl::fuzzer::Evaluator<E,EM,I,S>>::evaluate_input_events
  11: ityfuzz::fuzzers::evm_fuzzer::evm_fuzzer
  12: cli::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

panic: called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Request, url: Url { scheme: "...

Sentry Issue: RUST-6

panic: called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Request, url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("fuzz.land")), port: None, path: "/free", query: None, fragment: None }, source: hyper::Error(Connect, ConnectError("dns error", Custom { kind: Uncategorized, error: "failed to lookup address information: Temporary failure in name resolution" })) }
  File "panicking.rs", line 584, in rust_begin_unwind
  ?, in cli::licensing::init_license
  ?, in cli::main
  ?, in main
  ?, in _start
...
(15 additional frame(s) were not displayed)

False positives

I'm encountering some false positives with the latest build. I'm not 100% sure they are false positives so I'd rather discuss the details in private.

Could we talk again on Discord/Twitter and check if they are indeed FP's and so that I can get some insight in which of the currently planned improvements are expected to fix them? Thanks

panicked at 'Invalid chain type'

The contract I was testing https://etherscan.io/address/0x84db6ee82b7cf3b47e8f19270abde5718b936670.
And i tried to cancelled the campaign and cannot remove it from the results section. It keeps getting back.

thread 'main' panicked at 'Invalid chain type', src/main.rs:135:29
stack backtrace:
   0: rust_begin_unwind
             at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/core/src/panicking.rs:142:14
   2: core::panicking::panic_display
             at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/core/src/panicking.rs:72:5
   3: core::panicking::panic_str
             at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/core/src/panicking.rs:56:5
   4: core::option::expect_failed
             at /rustc/432abd86f231c908f6df3cdd779e83f35084be90/library/core/src/option.rs:1880:5
   5: cli::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Question about current balance of target

Does Ityfuzz look at the current balance (onchain fuzzing) of a target contract or does it assume the target has a high balance to simulate a possible hack?

It would make sense to assume a high balance if you want to look for possible vulnerabilities, even though they cannot be exploited at the moment. However, it does cause false positives.

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: InvalidHexCharacter { c: '<', index: 0 }'

Using latest compiled cli version with proxy & flashloan v2.

  • It seems to happen at random moments during fuzzing
  • Doesn't happen when I set --onchain-block-number to 0
  • On BSC chain
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: InvalidHexCharacter { c: '<', index: 0 }', /home/rappie/Desktop/ityfuzz.git/src/evm/onchain/endpoints.rs:557:74
stack backtrace:
   0: rust_begin_unwind
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/std/src/panicking.rs:577:5
   1: core::panicking::panic_fmt
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:67:14
   2: core::result::unwrap_failed
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/result.rs:1687:5
   3: ityfuzz::evm::onchain::endpoints::OnChainConfig::get_contract_slot
   4: <ityfuzz::evm::onchain::onchain::OnChain<VS,I,S> as ityfuzz::evm::middleware::Middleware<VS,I,S>>::on_step
   5: <ityfuzz::evm::host::FuzzHost<VS,I,S> as revm::evm_impl::Host<S>>::step
   6: revm::interpreter::Interpreter::run
   7: ityfuzz::evm::vm::EVMExecutor<I,S,VS>::execute_from_pc
   8: <ityfuzz::evm::vm::EVMExecutor<I,S,VS> as ityfuzz::generic_vm::vm_executor::GenericVM<VS,revm::interpreter::bytecode::Bytecode,bytes::bytes::Bytes,primitive_types::H160,primitive_types::H160,primitive_types::U256,alloc::vec::Vec<u8>,I,S>>::execute
   9: <ityfuzz::executor::FuzzExecutor<VS,Addr,Code,By,Loc,SlotTy,Out,I,S,OT> as libafl::executors::Executor<EM,I,S,Z>>::run_target
  10: <(Head,Tail) as libafl::stages::StagesTuple<E,EM,S,Z>>::perform_all
  11: <ityfuzz::fuzzer::ItyFuzzer<VS,Loc,Addr,Out,CS,IS,F,IF,I,OF,S,OT> as libafl::fuzzer::Fuzzer<E,EM,I,S,ST>>::fuzz_loop
  12: ityfuzz::fuzzers::evm_fuzzer::evm_fuzzer
  13: cli::main

Still getting `Invalid chain type` with latest docker image

Chain type: ETH

Started docker image using:

docker pull fuzzland/ityfuzz:stable
docker run -p 8000:8000 fuzzland/ityfuzz:stable
thread 'main' panicked at 'Invalid chain type', src/main.rs:170:57
stack backtrace:
   0: rust_begin_unwind
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/std/src/panicking.rs:577:5
   1: core::panicking::panic_fmt
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:67:14
   2: core::panicking::panic_display
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:150:5
   3: core::panicking::panic_str
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/panicking.rs:134:5
   4: core::option::expect_failed
             at /rustc/af06dce64bf87ea9206bdf6cff61c144b9ce8458/library/core/src/option.rs:2025:5
   5: cli::main

Viewing coverage % on chain fuzzing

Hi,

I'm currently exploring onchain fuzzing, and I was wondering if there's a way to track the coverage percentage as the fuzzing process progresses.

Ideally, I'd like to see how much of the code is being covered as the fuzzer runs, so that I can get a better sense of the effectiveness.

Is there any existing functionality in place that would allow me to do this?

Thanks for your help!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.