Giter Club home page Giter Club logo

optik's Introduction

Optik

Optik is a set of symbolic execution tools that assist smart contract fuzzers, letting them run in a hybrid mode. Optik couples Echidna, our smart contract fuzzer, with the Maat symbolic executor that replays the fuzzing corpus and extends it with new inputs that increase coverage.

Current limitations

Optik is a work in progress and should not be used for real audits yet. Current limitations include:

  • Symbolic KECCAK hashes are not supported
  • CREATE2, CALLCODE, and DELEGATECALL are not yet supported
  • Gas is not taken into account
  • Some echidna options are not yet supported (see hybrid-echidna -h)

Hybrid Echidna


Optik allows to run the Echidna smart-contract fuzzer in hybrid mode. It basically couples Echidna with the Maat symbolic executor that replays the Echidna corpus and extends it with new inputs that increase coverage.

hybrid-echidna starts with several incremental seeding steps, where it seeds the corpus with short transactions sequences obtained by Slither's dataflow analysis, and uses symbolic execution more intensely to solve new inputs. The sequence length is incremented at each seeding step. Once it reaches a certain length threshold, hybrid-echidna falls back into its normal mode, starts to limit the number of symbolic inputs to solve, and stops using dataflow analysis for seeding the corpus.

Usage

Hybrid echidna can be used seamlessly in place of regular Echidna by replacing echidna-test with hybrid-echidna in your Echidna command line. For example:

hybrid-echidna MyContract.sol  --test-mode assertion --corpus-dir /tmp/test --contract MyContract

Additionnal options are available in hybrid mode to control hybrid-echidna's behaviour:

  • --max-iters: maximum number of fuzzing iterations to perform (one iteration is one Echidna campaign + one symbolic executor run on the corpus)

  • --solver-timeout: maximum time in milliseconds to spend solving each possible new input

  • --incremental-threshold: number of initial incremental seeding steps to perform

  • --no-incremental: skip initial incremental seeding

  • --cov-mode: type of coverage to increase when solving new inputs. Most coverage modes are implemented for experimental purposes. Unless you are developing/hacking on Optik, we recommend to keep the default mode

Debugging, logging and terminal display:

  • --debug: add debugging information to the log output

  • --logs: write logs to a given file (or stdout)

  • --no-display: disable the graphical terminal display

Installation

For a quick installation, run:

python3 -m pip install optik-tools

To keep up with the latest features and fixes, install Optik from its master branch:

git clone https://github.com/crytic/optik && cd optik
python3 -m pip install .

You can also run it from Docker:

git clone https://github.com/crytic/optik && cd optik
docker build -t crytic/optik .
docker run -it --rm --mount type=bind,source="$(pwd)",target=/workdir crytic/optik
# This runs the Docker container, mounting the local directory into /workdir

optik's People

Contributors

0xalpharush avatar boyan-milanov avatar dguido avatar esultanik avatar montyly avatar oldsj avatar thomas-malcolm 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

optik's Issues

User-friendly terminal display for `hybrid-echidna`

hybrid-echidna currently displays its logs in the terminal while running. While this is great to know what goes on under the hood, it is not very practical to scroll through it. This is especially true when running a large number of Echidna campaigns and detecting a log of potential new paths, which makes the log very verbose.

We should add a command line option to let users decide whether they want the logs to be written in a file or to the terminal with --logs <file> or --logs <stdout>. If the option is stdout or not specified, we should then display some user-friendly info in the terminal:

  • current task: running echidna / replaying inputs / solving inputs
  • current task progress: with a counter, e.g Solving 4/256, and a progress bar
  • global stats: number of bugs found, number of new inputs generated, number of solver timeouts, etc...

Detect early success in coverage tests

Currently the unit tests for hybrid-echidna let the tool run as long as it finds new inputs. For some of the tests, this means that hybrid-echidna keeps running long after all the test target have been covered, which means that a lot of time is wasted.

We should have a way to detect when the coverage tests succeed, and force stop hybrid-echidna in that case. Probably a watcher that periodically checks the coverage file and kills hybrid-echidna in case of success could do the trick.

Latest optik fails with "SyntaxError: annotated name 'glob_fuzzing_result' can't be global"

Traceback (most recent call last):
  File "/home/g/.local/bin/hybrid-echidna", line 5, in <module>
    from optik.echidna.__main__ import main
  File "/home/g/.local/lib/python3.7/site-packages/optik/echidna/__init__.py", line 1, in <module>
    from .__main__ import run_hybrid_echidna
  File "/home/g/.local/lib/python3.7/site-packages/optik/echidna/__main__.py", line 545
    glob_fuzzing_result: Optional[FuzzingResult] = None
    ^
SyntaxError: annotated name 'glob_fuzzing_result' can't be global

Support Echidna initialisation files

Describe the bug
A JSON formatted initialisation file can be passed to Echidna through a config file. It can be used to setup an initial state before starting to fuzz the target contract. In particular it can be used to deploy arbitrary contracts at hardcoded addresses, with whom the target will interact.

Optik currently doesn't support the initialisation file and doesn't take it into account, which can cause fuzzing harnesses to not behave as expected.

To Reproduce
Example init.json contents:

[
  {
    "event": "AccountCreated",
    "address": "0x5AEDA56215b167893e80B4fE645BA6d5Bab767DE"
  },
  {
    "event": "ContractCreated",
    "from": "0x627306090abaB3A6e1400e9345bC60c78a8BEf57",
    "contract_address": "0x8CdaF0CD259887258Bc13a92C0a6dA92698644C0",
    "gas_used": "0x0b890a",
    "gas_price": "0x04a817c800",
    "data": "0x60606040  .....",
    "value": "0x00"
  },

And in echidna's config:

initialize: ./ops/init.json

Feature request: multiprocessing support

  • Allow to run N number of Echidna instances per iteration (check echidna-parade code for that)
  • Allow to run N number of smt solvers per iteration

Make sure the results are synced in single corpus before starting the new iteration

Limit delay between transactions

hybrid-echidna makes the delay between transactions symbolic, since it might affect the behaviour of contracts and be the cause of a bug. However, we should constrain the delay to a "reasonable" value in the context of an attack.

Echidna uses a ;ax delay of 1 week

Add storage-sensitive code coverage

Echidna has a storage-sensitive way of computing coverage. The "coverage state" consists not only of the covered instructions, but also the state of the contract storage when executing the instruction. The storage state itself consists of the set of storage addresses that were used (to read or write).

We should either extend InstCoverage or create a separate coverage tracker that implements this notion of coverage.
We should make sure that this strategy can pass the MultiMagic.sol coverage test.

Add `pymaat` in the requirements

Do this once the 0.6 Maat release packages are available on PyPI. This way users don't need to manually build the dev-evm Maat branch anymore.

Bug: KeyError crash when running `hybrid-echidna`

Describe the bug
It runs echidna for about 2 minutes and then crashes.

To Reproduce
Sadly I cannot share my environment. I could narrowing things down with some guidance.

Additional context:

  • Manjaro Linux, Python 3.10.8
  • Echidna 2.0.3
  • Slither 0.9.1
❯ poetry run hybrid-echidna . --contract E2E --config echidna-config.yaml --no-display --debug --logs stdout
ERROR:CryticCompile:Solidity 0.8.7 is not fully supported yet. You can still use Hardhat, but some features, like stack traces, might not work correctly.

Learn more at https://hardhat.org/reference/solidity-support"


2022-11-05 20:55:49,076 - INFO - Running echidna campaign #1 ...
2022-11-05 20:55:49,076 - DEBUG - Echidna invocation cmdline: echidna-test . --sender 10000 --sender 20000 --sender 30000 --contract E2E --corpus-dir ./tmp4bh5i9r2 --test-mode assertion --seq-len 1 --config echidna-config.yaml --test-limit 50000 --contract-addr 00A329C0648769A73AFAC7F9381E08FB43DBEA72 --deployer 30000 --format json
...

LOTS of errors

...
[5290,3483,0,"ErrorRevert"],[5291,3484,0,"ErrorRevert"],[5292,3485,0,"ErrorRevert"],[5315,3498,0,"ErrorRevert"],[5316,3499,0,"ErrorRevert"],[5321,3500,0,"ErrorRevert"],[5323,3501,0,"ErrorRevert"],[5324,3502,0,"ErrorRevert"],[5326,3503,0,"ErrorRevert"],[5327,3504,0,"ErrorRevert"],[5329,3505,0,"ErrorRevert"],[5331,3506,0,"ErrorRevert"],[5332,3507,0,"ErrorRevert"],[5334,3508,0,"ErrorRevert"],[5336,3509,0,"ErrorRevert"]]}}
2022-11-05 20:57:35,462 - DEBUG - Bytecode for contract E2E written in /tmp/optik_contract_8dd5ze2x.sol
2022-11-05 20:57:35,468 - INFO - Replaying 17 new inputs symbolically...
2022-11-05 20:57:35,468 - DEBUG - Replaying input: -3484589115831615002.txt
Traceback (most recent call last):
  File "/home/rappie/.cache/pypoetry/virtualenvs/optik-test-D8mu_njD-py3.10/bin/hybrid-echidna", line 8, in <module>
    sys.exit(main())
  File "/home/rappie/.cache/pypoetry/virtualenvs/optik-test-D8mu_njD-py3.10/lib/python3.10/site-packages/optik/echidna/__main__.py", line 521, in main
    func(sys.argv[1:])
  File "/home/rappie/.cache/pypoetry/virtualenvs/optik-test-D8mu_njD-py3.10/lib/python3.10/site-packages/optik/echidna/__main__.py", line 257, in run_hybrid_echidna
    replay_inputs(new_inputs, contract_file, deployer, cov)
  File "/home/rappie/.cache/pypoetry/virtualenvs/optik-test-D8mu_njD-py3.10/lib/python3.10/site-packages/optik/echidna/runner.py", line 81, in replay_inputs
    assert world.run() == STOP.EXIT
  File "/home/rappie/.cache/pypoetry/virtualenvs/optik-test-D8mu_njD-py3.10/lib/python3.10/site-packages/optik/common/world.py", line 376, in run
    self.current_contract.pop_runtime()
  File "/home/rappie/.cache/pypoetry/virtualenvs/optik-test-D8mu_njD-py3.10/lib/python3.10/site-packages/optik/common/world.py", line 283, in current_contract
    return self.contracts[self.call_stack[-1]]
KeyError: 3638658538924045119126437326771845363306064498

assert world.run() == STOP.EXIT failed

Optik compiled from master (cd95a61) crashes:

/usr/lib/python3/dist-packages/requests/__init__.py:89: RequestsDependencyWarning: urllib3 (1.26.7) or chardet (3.0.4) doesn't match a supported version!
  warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported "
Traceback (most recent call last):
  File "/home/g/.local/bin/hybrid-echidna", line 8, in <module>
    sys.exit(main())
  File "/home/g/.local/lib/python3.8/site-packages/optik/echidna/__main__.py", line 521, in main
    func(sys.argv[1:])
  File "/home/g/.local/lib/python3.8/site-packages/optik/echidna/__main__.py", line 311, in run_hybrid_echidna_with_display
    raise exc
  File "/home/g/.local/lib/python3.8/site-packages/optik/echidna/__main__.py", line 288, in run_hybrid_echidna_with_display
    run_hybrid_echidna(args)
  File "/home/g/.local/lib/python3.8/site-packages/optik/echidna/__main__.py", line 257, in run_hybrid_echidna
    replay_inputs(new_inputs, contract_file, deployer, cov)
  File "/home/g/.local/lib/python3.8/site-packages/optik/echidna/runner.py", line 81, in replay_inputs
    assert world.run() == STOP.EXIT
AssertionError

To reproduce, you can run:

$ hybrid-echidna crash.sol --test-mode assertion --contract C

using the following contract:

contract C {
    event E();
    function f() public {
        emit E();
    }
}

Extract the `echidna.__main__` script into a separate file

In order to make things more modular, the code of echidna.__main__ should be extracted into a separate file, for instance runner.py.

It could probably also be a good idea to split the script in two functions:

  • replay_inputs(m: MaatEngine, corpus_dir: str, contract_file: str, cov: Optional[InstCoverage]) -> InstCoverage: which replays all corpus inputs and returns the corresponding coverage. It should also accept an optional existing coverage manager cov, that could come from previous runs on the same contract.
  • find_new_inputs(cov: InstCoverage): which, given coverage information, uses the solver to find inputs that hit new code areas.

Report encountered limitation

Describe the bug
When running optik against a contract that includes symbolic keccak or delegate call or any other known limitation, it should exit gracefully with a description of the limitation encountered.

Currently, it crashes & produces a stack trace such as the one below, which does not indicate that the problem it encountered is a known limitation.

$ hybrid-echidna src/v0.8/Echidna.sol --contract Echidna --test-mode assertion --config ops/echidna.conf.yaml
Traceback (most recent call last):
  File "/Users/bohendo/.pyenv/versions/optik/bin/hybrid-echidna", line 8, in <module>
    sys.exit(main())
  File "/Users/bohendo/.pyenv/versions/optik/lib/python3.9/site-packages/optik/echidna/__main__.py", line 521, in main
    func(sys.argv[1:])
  File "/Users/bohendo/.pyenv/versions/optik/lib/python3.9/site-packages/optik/echidna/__main__.py", line 311, in run_hybrid_echidna_with_display
    raise exc
  File "/Users/bohendo/.pyenv/versions/optik/lib/python3.9/site-packages/optik/echidna/__main__.py", line 288, in run_hybrid_echidna_with_display
    run_hybrid_echidna(args)
  File "/Users/bohendo/.pyenv/versions/optik/lib/python3.9/site-packages/optik/echidna/__main__.py", line 257, in run_hybrid_echidna
    replay_inputs(new_inputs, contract_file, deployer, cov)
  File "/Users/bohendo/.pyenv/versions/optik/lib/python3.9/site-packages/optik/echidna/runner.py", line 81, in replay_inputs
    assert world.run() == STOP.EXIT
AssertionError

To Reproduce
Run optik against a contract that includes a known limitation.

Add coverage tests

Once #9 is addressed we should work on adding a set of coverage tests. The tests will consist in running the hybrid fuzzer on contracts containing hard path conditions, and verify that we can successfully generate inputs that cover all the paths.

Implementation: each path can return a unique value. We can then check if coverage is complete by replaying the entire final corpus and making sure that we see all possible return values at least once.

Bug: Crash when starting `hybrid-echidna` in `tmux`

It works in urxvt and Konsole when not in tmux. But when I run it in tmux it crashes with this error:

❯ poetry run hybrid-echidna . --contract E2E --config echidna-config.yaml
Exception in thread Thread-1 (_display):
Traceback (most recent call last):
  File "/usr/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "/home/rappie/.cache/pypoetry/virtualenvs/optik-test-D8mu_njD-py3.10/lib/python3.10/site-packages/optik/echidna/display.py", line 481, in _display
    raise exc
  File "/home/rappie/.cache/pypoetry/virtualenvs/optik-test-D8mu_njD-py3.10/lib/python3.10/site-packages/optik/echidna/display.py", line 459, in _display
    curses.init_color(curses.COLOR_RED, 245 * 4, 130 * 4, 0 * 4)
_curses.error: init_extended_color() returned ERR

Additional context:

  • Manjaro Linux, Python 3.10.8
  • Echidna 2.0.3
  • Slither 0.9.1

Optimisation ideas

Some brain dumping about optimisations for finding new paths:

  • consider only 1 or a subset of bifurcations that have the same alt_target
  • keep track of targets that are hard to reach (solver timeouts on them, etc, ...)

Support inputs with multiple transactions

There currently are limitations that prevent us from properly replay and generate inputs that consist of multiple transactions. In order to support multiple transactions we have to implement the following:

  • Proper symbolic variable naming according to the transaction they belong to (e.g tx0_arg2, tx1_arg0, ...)
  • Handle transaction number when serializing new inputs into the Echidna corpus
  • Test that EVMWorld correctly executes successive transactions 

Rename coverage modes

It seems that there were some misunderstanding about the notion of coverage used by Echidna. The echidna coverage strategy should be renamed/removed, and the default should probably set to inst-tx, unless we implement another coverage mode that is even closer to what Echidna does

Support running multiple solidity files

We should support multiple solidity files as input, and use the --contract argument to know which contract bytecode to read from the crytic-export directory

Note: this is not about supporting multiple contracts deployment

pointer being freed was not allocated and attribute error

Description

I followed the installation instructions in the readme and then ran the following command: hybrid-echidna Test.sol --contract Break. I get two separate errors when trying it again. Below is a test case and the --debug output for each error. Fwiw, I'm using Echidna 2.0.1

Test case

contract C {
  address owner = address(0);
  uint private stateA = 0;
  uint private stateB = 0;
  uint CONST = 32;

  constructor() { // Constructor
    owner = msg.sender;
  }

  function f(uint x) external {
    if (msg.sender == owner) { stateA = x; }

  }

  function g(uint y) external {
    if (stateA % CONST == 1) {
      stateB = y - 10;
    }
  }

  function h() external {
    if (stateB == 62) { echidna_bug(); }
  }

  function echidna_bug() private {
    assert(false);
  }
}

contract Break {
  C target;
  constructor() {
    target = new C();
  }

  function two(uint x, uint y) external {
    target.f(x);
    target.g(y);
    target.h();

  }
}

Log Output

Python(8222,0x10b6f1600) malloc: *** error for object 0x600028142980: pointer being freed was not allocated
Python(8222,0x10b6f1600) malloc: *** set a breakpoint in malloc_error_break to debug

Click to expand

2022-07-11 11:21:59,925 - INFO - Running echidna campaign #1 ...
2022-07-11 11:21:59,925 - DEBUG - Echidna invocation cmdline: echidna-test Test.sol --sender 10000 --sender 20000 --sender 30000 --contract Break --corpus-dir ./tmp87cd0kib --test-mode assertion --seq-len 100 --test-limit 50000 --contract-addr 00A329C0648769A73AFAC7F9381E08FB43DBEA72 --deployer 30000
2022-07-11 11:26:26,982 - DEBUG - Echidna stdout: 
Loaded total of 0 transactions from ./tmp87cd0kib/coverage
Analyzing contract: /Users/home/Desktop/slither-corpus/Test.sol:Break
two(uint256,uint256): passed! 🎉
AssertionFailed(..): passed! 🎉

Unique instructions: 638
Unique codehashes: 2
Corpus size: 2
Seed: -1753401289950974386

2022-07-11 11:26:26,986 - DEBUG - Bytecode for contract Break written in /var/folders/xk/vbz4_5j55h3dsvk2n5n4kyb00000gn/T/optik_contract_gezw1enl.sol
2022-07-11 11:26:26,986 - INFO - Replaying 2 new inputs symbolically...
2022-07-11 11:26:26,986 - DEBUG - Replaying input: -6815464574259696423.txt
2022-07-11 11:26:26,987 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:26,999 - DEBUG - Parsed arg values: [32, 115792089237316195423570985008687907853269984665640564039457584007913129639927] with types: ['uint256', 'uint256']
2022-07-11 11:26:26,999 - DEBUG - Parsed arg values: [115792089237316195423570985008687907853269984665640564039457584007913129639873, 32] with types: ['uint256', 'uint256']
2022-07-11 11:26:26,999 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:26,999 - DEBUG - Parsed arg values: [31, 23175145669444749602534806330610299930052980690542363006070416599876231033282] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,000 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,000 - DEBUG - Parsed arg values: [68753632696848621676112952575432419407189458248461732672842317056251734333303, 11666230830495442501274192135584749713833554890212495664569736144675196700184] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,000 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,000 - DEBUG - Parsed arg values: [84162070344295636241794266548464449049686487573250410543334460623286144970525, 115792089237316195423570985008687907853269984665640564039457584007913129639874] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,000 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,000 - DEBUG - Parsed arg values: [93041627520739632216512304449716938717494600589699717219177861093650711920033, 115792089237316195423570985008687907853269984665640564039457584007913129639903] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,000 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,001 - DEBUG - Parsed arg values: [54255843596541844760631344712085973794387034459953548829382718359005756944173, 14532967151693180284326880380764805506204698739540552692898073650132139367487] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,001 - DEBUG - Parsed arg values: [80906834931465722910343751430680751687728649619377609144906243704420982744508, 113352577921311872008582496228055932033349380490923904969055128953443517591640] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,001 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,001 - DEBUG - Parsed arg values: [34195566009227593473814626599705615573398246360491993672596199842371875751121, 115792089237316195423570985008687907853269984665640564039457584007913129639935] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,001 - DEBUG - Parsed arg values: [115792089237316195423570985008687907853269984665640564039457584007913129639934, 1524785992] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,001 - DEBUG - Parsed arg values: [41293207933531125193752343692462979707691333378530113713627295318718226876903, 115792089237316195423570985008687907853269984665640564039457584007913129639875] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,002 - DEBUG - Parsed arg values: [9656641236370195909368657957962243243382732746577149405295021910773167687562, 33] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,002 - DEBUG - Parsed arg values: [115792089237316195423570985008687907853269984665640564039457584007913129639874, 115792089237316195423570985008687907853269984665640564039457584007913129639874] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,002 - DEBUG - Parsed arg values: [62130272563476981497066162778501636974322338551334301793939368715038753095872, 6776799094494549448495092884294495530018466428834227845066566756263147745769] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,002 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,002 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,002 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,002 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,003 - DEBUG - Parsed arg values: [115792089237316195423570985008687907853269984665640564039457584007913129639934, 874] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,003 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,003 - DEBUG - Parsed arg values: [1524785992, 408] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,003 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,003 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,003 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,003 - DEBUG - Parsed arg values: [115792089237316195423570985008687907853269984665640564039457584007913129639905, 115792089237316195423570985008687907853269984665640564039457584007913129639875] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,003 - DEBUG - Parsed arg values: [63, 63] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,003 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,003 - DEBUG - Parsed arg values: [32419071849473704371245771211277441539042093932387518755483176706777249051142, 106520254917745055711552471940284916753308285120749028170308530495946890344049] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,004 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,004 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,004 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,004 - DEBUG - Parsed arg values: [15576672461052599946928292523851793126383674118099684640482035076732090145748, 4369999] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,004 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,004 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,004 - DEBUG - Parsed arg values: [32, 115792089237316195423570985008687907853269984665640564039457584007913129639926] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,004 - DEBUG - Parsed arg values: [49919325508694234305209921999548470584162621106574126142003692546686825146178, 4370000] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,004 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,005 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,005 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,005 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,005 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,005 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,005 - DEBUG - Parsed arg values: [18794259336639425314558529098990069942099531761456239206554510154101617603878, 102410684690574899122282139316327717830187308749729104899483416046764602070308] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,005 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,005 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,005 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,005 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,006 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,012 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,012 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,012 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,012 - DEBUG - Parsed arg values: [521719642602471589323695956383223593991357241015750961584756593452260244401, 10] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,012 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,012 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,013 - DEBUG - Parsed arg values: [475, 115792089237316195423570985008687907853269984665640564039457584007913129639873] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,013 - DEBUG - Parsed arg values: [2360761772346008190391421133107922821584268226778873357611646062731983620182, 63] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,013 - DEBUG - Parsed arg values: [43773661452569051811570616575040006402107740502027587372317570847688680908343, 11762126280972801157266707685316488333513831581092245312238697864615950427355] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,013 - DEBUG - Parsed arg values: [408, 68821867076226192810663109867236479255653128669457616569246172723014336354558] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,013 - DEBUG - Parsed arg values: [62, 33959031556959098928863736321425378314036058357592813592358293040189210471574] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,013 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,013 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,014 - DEBUG - Parsed arg values: [16554958434015270150241471160437808762074444130844228926818045237857774429221, 62] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,014 - DEBUG - Parsed arg values: [391, 34096110105207695369543691843123733153928252891765970667105967008649855542200] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,014 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,014 - DEBUG - Parsed arg values: [35152771995040563053182667255442118745988125510723392143342276517161409966556, 4370001] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,014 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,014 - DEBUG - Parsed arg values: [52921548158880970853711182342450115287882378647381108100025802077126444425074, 68589958287885506160465901943143642365128024468112966130599982723338272928044] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,014 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,015 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,015 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,015 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,015 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,015 - DEBUG - Parsed arg values: [92850181106908002403288325346572281546382432100344148743534804014320688294143, 76787345584674268108094702203223288099110718644548518122559062611821209205061] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,015 - DEBUG - Parsed arg values: [115792089237316195423570985008687907853269984665640564039457584007913129639875, 61470672580314338929087913747940156464202776446566630564307475066425754056378] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,015 - DEBUG - Parsed arg values: [115792089237316195423570985008687907853269984665640564039457584007913129639875, 109228560952237607056046325743180154621523211664526551601092874462237282873504] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,015 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,015 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,016 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,016 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,016 - DEBUG - Parsed arg values: [34324717905075217657186570865912467316461446043348648969889154399559450235163, 17943967601260452392191376824412096701866945043452104298125180297605566355988] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,018 - DEBUG - Parsed arg values: [73790844812036587515198133400480635507080135575399179936899292107422381219709, 39726450129653643527346805242616168923624291243978297810679978722795382780320] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,018 - DEBUG - Parsed arg values: [0, 11930879620023418951822360224058437469422103461967128922454340338627060921761] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,019 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,019 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,019 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,019 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,019 - DEBUG - Parsed arg values: [81666149733324592589807644771051732208807546808876070550658064681560036457347, 95961685539886512655455002039253415700437056359783484989249891940493649960518] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,019 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,021 - DEBUG - Parsed arg values: [66280171745175094166126154051688150541205776483104001959256458401813931083144, 14484345954093118397586153550495930856427206437431286437729752734668968595668] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,021 - DEBUG - Parsed arg values: [115792089237316195423570985008687907853269984665640564039457584007913129639905, 72771734939017075179202952698298611289948794147237072610500465769855926436880] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,022 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,022 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,022 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,536 - DEBUG - Replaying input: -2502972617776732782.txt
2022-07-11 11:26:27,536 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,537 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,537 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,537 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,537 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,537 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,537 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,537 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,538 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,538 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,538 - DEBUG - Parsed arg values: [85023223901033574536149017643915356510652484271195756843722394066092204234142, 108697930402358702402370649881499695663266387326024425294562430505850616586189] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,538 - DEBUG - Parsed arg values: [41336767828719776149602610714493743784626948292274680176339802977888039777819, 7270988173424145031993171659039958077503563587420961210066004047169225831454] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,538 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,538 - DEBUG - Parsed arg values: [4370001, 93305827783646895910027715358817263697747867977658051535281040184277556698381] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,538 - DEBUG - Parsed arg values: [4370000, 10] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,539 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,539 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,539 - DEBUG - Parsed arg values: [1524785992, 44900100745315194435428421200303636257789949365311172175916812082424312963390] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,539 - DEBUG - Parsed arg values: [79483762578797351596563950999410247194595582907917687121684244975182673392666, 115792089237316195423570985008687907853269984665640564039457584007913129639927] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,539 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,539 - DEBUG - Parsed arg values: [103124071330759285956579121949483431748186594453309264626590383089888642472061, 2111219522884817580889462310721625310472061557377430574587877433545997968820] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,540 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,540 - DEBUG - Parsed arg values: [115792089237316195423570985008687907853269984665640564039457584007913129639927, 31] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,540 - DEBUG - Parsed arg values: [44037510228220239815774668126402258983261434854440302799182693140895644102965, 115792089237316195423570985008687907853269984665640564039457584007913129639934] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,540 - DEBUG - Parsed arg values: [79374164494404755316817944163552247274043669655596520610625953277639530795537, 34872693101597317595106225841389763544163458773410772828620064888418413868547] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,540 - DEBUG - Parsed arg values: [99330153604914113202836706570845676737281675587712444559481189000860596253547, 89432408381048567326194915044609889142574740003374744991775619006357918627996] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,541 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,541 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,541 - DEBUG - Parsed arg values: [900, 357] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,541 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,541 - DEBUG - Parsed arg values: [33, 9] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,541 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,541 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,542 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,542 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,542 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,542 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,542 - DEBUG - Parsed arg values: [77217853076945002746886598718139371249448431370219299252400426709650229267578, 101252415267404541494214254827396655931581383630324607631317221183771207124471] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,542 - DEBUG - Parsed arg values: [30894729498150507774094120721954220113673408119695554882261586710660424443283, 26764642536816834362120489889940410686992206373784073330452445681590654897391] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,542 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,542 - DEBUG - Parsed arg values: [613, 101528486385396501700664235859773909580529027600585042177168880356849140000220] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,542 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,543 - DEBUG - Parsed arg values: [57183139199244729508911541714994917615121691580905327358552265883059081647926, 40276636735705877118856015985701544924317135740705922726276907481321371734456] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,543 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,543 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,543 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,543 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,543 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,543 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,543 - DEBUG - Parsed arg values: [1, 115792089237316195423570985008687907853269984665640564039457584007913129639927] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,545 - DEBUG - Parsed arg values: [9, 90703815904633781665814102472243983472691388058254665108609606123466341436005] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,545 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,545 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,545 - DEBUG - Parsed arg values: [17503248389119125907796814156989115113118367682257404596839672825565190493154, 10] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,545 - DEBUG - Parsed arg values: [21629282249708234083089544516702866770415436145372095456727624970970080470652, 54826794983609617139995396669459197829987833768633193423916164286582137605742] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,545 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,545 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,546 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,546 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,546 - DEBUG - Parsed arg values: [65807688924808796130661709845082273669124863509779121681613200677352596362477, 10] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,546 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,546 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,546 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,546 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,546 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,546 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,547 - DEBUG - Parsed arg values: [67797903345728124360700692245240662028161562463814959492823235821127720150045, 28978307701195286189489385758180462341232762354794502892706067896214319162397] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,547 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,547 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,547 - DEBUG - Parsed arg values: [61748186214447348526097670719844409968131007564146734913277786775606540939880, 33] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,547 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,547 - DEBUG - Parsed arg values: [62, 115792089237316195423570985008687907853269984665640564039457584007913129639934] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,547 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,547 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,547 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,548 - DEBUG - Parsed arg values: [113755872135738886217072974055760681969845975117046683853004378541822148473123, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,548 - DEBUG - Parsed arg values: [32, 115792089237316195423570985008687907853269984665640564039457584007913129639927] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,548 - DEBUG - Parsed arg values: [115792089237316195423570985008687907853269984665640564039457584007913129639873, 32] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,548 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,548 - DEBUG - Parsed arg values: [31, 23175145669444749602534806330610299930052980690542363006070416599876231033282] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,548 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,548 - DEBUG - Parsed arg values: [68753632696848621676112952575432419407189458248461732672842317056251734333303, 11666230830495442501274192135584749713833554890212495664569736144675196700184] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,548 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,548 - DEBUG - Parsed arg values: [84162070344295636241794266548464449049686487573250410543334460623286144970525, 115792089237316195423570985008687907853269984665640564039457584007913129639874] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,549 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,549 - DEBUG - Parsed arg values: [93041627520739632216512304449716938717494600589699717219177861093650711920033, 115792089237316195423570985008687907853269984665640564039457584007913129639903] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,549 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,549 - DEBUG - Parsed arg values: [54255843596541844760631344712085973794387034459953548829382718359005756944173, 14532967151693180284326880380764805506204698739540552692898073650132139367487] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,549 - DEBUG - Parsed arg values: [80906834931465722910343751430680751687728649619377609144906243704420982744508, 113352577921311872008582496228055932033349380490923904969055128953443517591640] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,549 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,549 - DEBUG - Parsed arg values: [34195566009227593473814626599705615573398246360491993672596199842371875751121, 115792089237316195423570985008687907853269984665640564039457584007913129639935] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,550 - DEBUG - Parsed arg values: [115792089237316195423570985008687907853269984665640564039457584007913129639934, 1524785992] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,550 - DEBUG - Parsed arg values: [41293207933531125193752343692462979707691333378530113713627295318718226876903, 115792089237316195423570985008687907853269984665640564039457584007913129639875] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,550 - DEBUG - Parsed arg values: [9656641236370195909368657957962243243382732746577149405295021910773167687562, 33] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,550 - DEBUG - Parsed arg values: [115792089237316195423570985008687907853269984665640564039457584007913129639874, 115792089237316195423570985008687907853269984665640564039457584007913129639874] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,550 - DEBUG - Parsed arg values: [62130272563476981497066162778501636974322338551334301793939368715038753095872, 6776799094494549448495092884294495530018466428834227845066566756263147745769] with types: ['uint256', 'uint256']
2022-07-11 11:26:27,550 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,551 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,551 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:26:27,551 - DEBUG - Parsed arg values: [] with types: []
Python(8222,0x10b6f1600) malloc: *** error for object 0x600028142980: pointer being freed was not allocated
Python(8222,0x10b6f1600) malloc: *** set a breakpoint in malloc_error_break to debug

if caller_contract.outgoing_transaction.type in [
AttributeError: 'NoneType' object has no attribute 'type'

Click to expand

2022-07-11 11:28:57,456 - INFO - Running echidna campaign #1 ...
2022-07-11 11:28:57,456 - DEBUG - Echidna invocation cmdline: echidna-test Test.sol --sender 10000 --sender 20000 --sender 30000 --contract Break --corpus-dir ./tmp81l54_df --test-mode assertion --seq-len 100 --test-limit 50000 --contract-addr 00A329C0648769A73AFAC7F9381E08FB43DBEA72 --deployer 30000
2022-07-11 11:33:36,770 - DEBUG - Echidna stdout: 
Loaded total of 0 transactions from ./tmp81l54_df/coverage
Analyzing contract: /Users/home/Desktop/slither-corpus/Test.sol:Break
two(uint256,uint256): passed! 🎉
AssertionFailed(..): passed! 🎉

Unique instructions: 638
Unique codehashes: 2
Corpus size: 2
Seed: -2637173933097358928

2022-07-11 11:33:36,776 - DEBUG - Bytecode for contract Break written in /var/folders/xk/vbz4_5j55h3dsvk2n5n4kyb00000gn/T/optik_contract_emt8amqa.sol
2022-07-11 11:33:36,778 - INFO - Replaying 2 new inputs symbolically...
2022-07-11 11:33:36,778 - DEBUG - Replaying input: -2850432582186042527.txt
2022-07-11 11:33:36,779 - DEBUG - Parsed arg values: [79897487338287567690609829132503250316048607412581496660847150826358722764598, 105235564760092021996799375254561114713969648341925896467707093344824500620799] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,790 - DEBUG - Parsed arg values: [4108915295030980255647859117754396300355271502235548555858922393992365935564, 111633731421565988004290543263518729778692475942867821458682070252141228721229] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,790 - DEBUG - Parsed arg values: [83141588221417932736702797792740540401240796072129941748633749212116689691332, 4067208581491684344976700948122002795663821641226198094376437574207739827138] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,791 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,791 - DEBUG - Parsed arg values: [44789265113077006473967601850162453686508843558709101976932119614421374117344, 101080304052919848857449613197201264168535988313197793246984656880532982488987] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,791 - DEBUG - Parsed arg values: [632, 30105588533357346933850793102790601851851054663224133816472805368058989458093] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,791 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,791 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,792 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,792 - DEBUG - Parsed arg values: [33, 2] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,792 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,792 - DEBUG - Parsed arg values: [33, 78708191372750723149736794514867507381263474835672711550508347555584968281888] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,792 - DEBUG - Parsed arg values: [15741493484159460292789025741135779044012412598731788466242922558458776811116, 115792089237316195423570985008687907853269984665640564039457584007913129639873] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,793 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,793 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,793 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,793 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,793 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,793 - DEBUG - Parsed arg values: [79378053835534957309735256811425196596138858852931596284379478340903605169850, 83993172101052890109990462524035802622721366653398493727569348797834308376273] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,793 - DEBUG - Parsed arg values: [24771116194626158875797646403248047201059716398090303534250231504570798312907, 4370001] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,794 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,794 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,794 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,794 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,794 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,794 - DEBUG - Parsed arg values: [75513791636050875467145647486422306897288272603652317202801050057198493899385, 74808247746441716890714784674332564861800509810814753326098227361123279216574] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,794 - DEBUG - Parsed arg values: [4370000, 421642730724795799860239518531385975363347678470317106462786958241875896422] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,794 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,795 - DEBUG - Parsed arg values: [110007578983019229358200135460737857154061484837613888337105967760546116316854, 67262625262877475915870557647313676357882309141014889385743218393766046809103] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,795 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,795 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,795 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,795 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,795 - DEBUG - Parsed arg values: [93442325851309961608928523584762747095877928692218459175501445142574854486590, 101983706566582197869396962589528676556515819233241239574568073414225567527925] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,795 - DEBUG - Parsed arg values: [84918564231784895906293657672989814957167305407518814401334979902545936999599, 11159554286966738101796630393287372006851310965290922725981735916991165576637] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,795 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,796 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,796 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,796 - DEBUG - Parsed arg values: [1061047339766371588601661773552045599777154385220824506670764339060869474941, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,796 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,796 - DEBUG - Parsed arg values: [1524785991, 33574702038919933894258200735770775284358775246123572443699999832443481732855] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,797 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,797 - DEBUG - Parsed arg values: [95015173102225856911747808822622053462752818812600720481213383392989347631727, 115792089237316195423570985008687907853269984665640564039457584007913129639874] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,797 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,797 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,797 - DEBUG - Parsed arg values: [33, 2] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,798 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,798 - DEBUG - Parsed arg values: [115792089237316195423570985008687907853269984665640564039457584007913129639875, 109871417036025521503698404792567232987573547990763438313907647384622312402335] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,798 - DEBUG - Parsed arg values: [69891872064195519713587122158559910518331021740881978353697339443786944226493, 98123357041629747860957831570235482901038752137963189666710792005892790172632] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,798 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,798 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,799 - DEBUG - Parsed arg values: [9, 75849853485492029474842969115818230584554975269787889232715043426833586460084] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,799 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,799 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,799 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,799 - DEBUG - Parsed arg values: [0, 353369564879819588182326105212423406236711111571384380415563703221570825313] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,799 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,799 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,799 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,800 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,800 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,800 - DEBUG - Parsed arg values: [115792089237316195423570985008687907853269984665640564039457584007913129639925, 31] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,800 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,800 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,800 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,800 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,800 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,801 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,801 - DEBUG - Parsed arg values: [51, 4369999] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,801 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,801 - DEBUG - Parsed arg values: [12257339044445854416903281223353920832358433395413548833202962842484929827134, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,801 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,801 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,802 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,803 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,803 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,803 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,803 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,803 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,803 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,803 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,803 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,804 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,804 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,804 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,804 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,804 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,804 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,804 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,804 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,804 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,804 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,805 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,805 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,805 - DEBUG - Parsed arg values: [62, 10] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,805 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,805 - DEBUG - Parsed arg values: [115792089237316195423570985008687907853269984665640564039457584007913129639904, 115792089237316195423570985008687907853269984665640564039457584007913129639904] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,805 - DEBUG - Parsed arg values: [] with types: []
2022-07-11 11:33:36,805 - DEBUG - Parsed arg values: [12248239235326689311842298318930006163032750184498401084747544610019062062280, 3693986454279137288840803197752070858763032747176457728711065365994631669778] with types: ['uint256', 'uint256']
2022-07-11 11:33:36,805 - DEBUG - Parsed arg values: [739, 32] with types: ['uint256', 'uint256']
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.10/bin/hybrid-echidna", line 8, in <module>
    sys.exit(main())
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/optik/echidna/__main__.py", line 259, in main
    run_hybrid_echidna(sys.argv[1:])
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/optik/echidna/__main__.py", line 92, in run_hybrid_echidna
    replay_inputs(new_inputs, contract_file, deployer, cov)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/optik/echidna/runner.py", line 69, in replay_inputs
    assert world.run() == STOP.EXIT
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/optik/common/world.py", line 353, in run
    if caller_contract.outgoing_transaction.type in [
AttributeError: 'NoneType' object has no attribute 'type'

Enforce `mypy`

We reached a point where we need to enforce mypy in the CI. This will probably result in many small fixes in the code, and also requires that Maat's python package properly exposes classes in its module.

Serialize discovered inputs in the Echidna JSON corpus format

We are using Echidna's JSON formatting of transactions in our Echidna interface. For example, a transaction calling foo(uint256) with the argument 42 can be encoded as follows:

[
   {
      "_gas'" : "0xffffffff",
      "_delay" : [
         "0x13647",
         "0xccf6"
      ],
      "_src" : "00a329c0648769a73afac7f9381e08fb43dbea70",
      "_dst" : "00a329c0648769a73afac7f9381e08fb43dbea72",
      "_value" : "0x0",
      "_call" : {
         "tag" : "SolCall",
         "contents" : [
            "foo",
            [
               {
                  "contents" : [
                     256,
                     "42"
                  ],
                  "tag" : "AbiUInt"
               },
            ]
         ]
      },
      "_gasprice'" : "0xa904461f1"
   }
]

We already have minimal support to load JSON transactions into palantir, but we still need to write an interface that writes back transaction data (which is returned as a List[Value]) into an Echidna JSON file.

The best approach would probably to copy the original input file and simply iterate through the function parameter fields and replace their values with the new values from the new input.

Bug: JSONDecodeError crash when running `hybrid-echidna`

Describe the bug
It runs echidna for about 2 minutes and then crashes.

To Reproduce
Sadly I cannot share my environment. I could narrowing things down with some guidance.

Additional context:

  • Manjaro Linux, Python 3.10.8
  • Echidna 2.0.4
  • Slither 0.9.1
❯ hybrid-echidna . --contract E2E --config echidna-config.yaml
Traceback (most recent call last):
  File "/home/rappie/.local/bin/hybrid-echidna", line 8, in <module>
    sys.exit(main())
  File "/home/rappie/.local/lib/python3.10/site-packages/optik/echidna/__main__.py", line 554, in main
    func(sys.argv[1:])
  File "/home/rappie/.local/lib/python3.10/site-packages/optik/echidna/__main__.py", line 344, in run_hybrid_echidna_with_display
    raise exc
  File "/home/rappie/.local/lib/python3.10/site-packages/optik/echidna/__main__.py", line 321, in run_hybrid_echidna_with_display
    run_hybrid_echidna(args)
  File "/home/rappie/.local/lib/python3.10/site-packages/optik/echidna/__main__.py", line 235, in run_hybrid_echidna
    nb_cov_insts = count_unique_pc(p.stdout)
  File "/home/rappie/.local/lib/python3.10/site-packages/optik/echidna/interface.py", line 523, in count_unique_pc
    data = json.loads(output)
  File "/usr/lib/python3.10/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.10/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.10/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Unexpectedly large number of paths that slow down what should be "simple"

When I run this example with Echidna, it broke all but one assertion, testNegativeMax1, very quickly. I expected for Optik to only try to solve this unbroken assertion as it should have counterexamples in the corpus for others, but it seemed "more difficult" of a problem than I imagined. Intuitively, counterexamples would be raise early on for the other assertions (this is understandable given the UI is still in the works). Also, I'd expect val != type(int256).max - 2 to be fed into an SMT solver and for a value to be found trivially. Just giving my feedback on UX... there's likely something I'm missing as Maat/Optik are a black box to me.

contract FuzzNumbersTest {

    function testNegativeHalf(int256 val) public {
        assert(val < 2 ** 128 - 1);
    }

    function testNegative0(int256 val) public {
        assert(val != 0);
    }

    function testNegative1(int256 val) public {
        assert(val != -1);
    }

    function testNegative2(int256 val) public {
        assert(val != 1);
    }

    function testNegativeMax0(int256 val) public {
        assert(val != type(int256).max);
    }

    function testNegativeMax1(int256 val) public {
        assert(val != type(int256).max - 2);
    }

    function testNegativeMin0(int256 val) public {
        assert(val != type(int256).min);
    }


    function testNegativeMin1(int256 val) public {
        assert(val != type(int256).min + 2);
    }

    function testEquality(int256 x, int256 y) public {
        int256 xy;

        unchecked {
            xy = x * y;
        }

        if ((x != 0 && xy / x != y)) return;

        assert(((xy - 1) / 1e18) + 1 == (xy - 1) / (1e18 + 1));
    }
}

Optik found many paths, Solving potential new paths... (2138 total, 604 unique), and ran for multiple hours.

Add unit-tests for corpus seeding

We should eventually add some unit-tests for corpus generation based on dataflow analysis with Slither. At the moment the dataflow analysis is very simple, so no tests are required. However when we decide to refine the analysis or support inter-contract dataflow it will be worth adding unitary tests that make sure that we find interesting transaction sequences for specific tailored examples.

Idea for optimised coverage

To investigate: add a coverage mode similar to inst-tx except that instead of the tx number we use the set of previously called functions. That is a subset of what inst-tx does and might help scale up to bigger contracts, while retaining interesting behaviour.

Support for symbolic KECCAK hashes

We need at least basic support for solving simple constraints that involve keccak hashes. Such as keccak(A) == keccak(B).

Interesting strategies are already implemented in Manticore and we can probably re-use most of them. This will probably require to write a Solver wrapper in Optik with some expression/constraint rewriting rules.

Unsound symbolication of `uint` type

Currently encode uint<M> arguments with a 32-byte padding. When the resulting value is made symbolic, the all 256 bits are made symbolic, instead of the actual M bits that can vary.

We must fix this in our encoder/symbolicator.

Feature request: capture all the stdout/stderr from crytic-compile/slither/echidna and save it at every iteration

In the current audit, I'm getting some stderr messages from crytic compile that break the console output:

ERROR:CryticCompile:Error HH12: Trying to use a non-local installation of Hardhat, which is not supported

This is a non-fatal error, but the console is disrupted.

On top of that, it could be very useful to save the echidna output, in case of some issue (e.g. it can crash because it uses too much memory) or because we want to see the exact output (e.g. events), without re-running a campaign.

Full echidna integration

Once #3 is done, we must modify the echidna main script so that it performs all the following steps automatically:

  1. run echidna
  2. replay (new) inputs from the corpus. We should keep an internal list of inputs that were already replayed to that they are not run more than once in Maat
  3. find new inputs and write them back in the corpus directory
  4. If new inputs were discovered, go back to step 1

We should add a command line argument to let the user specify how many iterations they want to do. We should probably also add an argument to pass an Echidna config file to use when invoking echidna.

Create a bug report issue template

We should create a Github issue template for bug reports which shows how to run hybrid-echidna in console mode and get the debug logs

Don't use symbolic transaction value on functions that are not `payable`

Currently Optik makes the transaction value symbolic. Since solidity code systematically results in value checks to ensure that value is null for non-payable functions, this adds a lot of symbolic branches that generate non-null transaction values, which is totally useless in practice.

We should make the transaction value symbolic only if the called function is payable

Error when encoding `uint<M>` types

I made an error in the abi.uintM() function: it should always return values padded to 256 bits, instead of <M> bits as indicated by the type.

Run entire Echidna corpus

For the moment, the __main__ script in the echidna submodule accepts a single corpus file as an argument. We should modify the script so that it instead takes the directory containing all the corpus files, and runs all the corpus files, before trying to find new inputs based on code coverage.

Support deploying and sending ETH to EOAs

Some contracts will send ETH to EOAs through message calls. We need to support deploying EOAs for such operations to be emulated properly.

There are two options for implementing this:

  • support deploying EOAs in Maat. It requires more work in Maat but should allow to handle calls to EOAs seamlessly in Optik, which is why this is the preferred solution
  • simulate EOAs in Optik directly. It can be scripted easily but will pollute the code with corner-case handlers, so it's a less elegant solution

For reference, this feature is needed to properly run this challenge: https://ethernaut.openzeppelin.com/level/0x5732B2F88cbd19B6f01E3a96e9f0D90B917281E5

Echidna manual seed in debug mode

Randomly generate (and log) a seed for Echidna to use when fuzzing for new input in debug mode so that behaviour can be reproduced in testing?

i.e. when we invoke Echidna through hybrid-echidna, we should pass the --seed <value> parameter through on the "cli", where <value> is a seed we generate internally, but only in debug mode.

Add more tests based on Echidna tests

Echidna has some interesting tests were it need to find specific input values. They are particularly well-suited to test hybrid fuzzing. The tests are found here: https://github.com/crytic/echidna/tree/master/tests/solidity/values

We should modify them and make them hard enough so that Echidna fails to solve them, and then show that we can solve them with hybrid-echidna, and make them part of our unit-tests.

For some of them we'll need to support more ABI types (see #14), and perhaps more EVM instructions in Maat.

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.