Skip to content

Commit

Permalink
mdbook for medusa (crytic#348)
Browse files Browse the repository at this point in the history
* Migrate to mdbook (crytic#223)

Co-authored-by: Zach McManus <[email protected]>
Co-authored-by: Damilola Edwards <[email protected]>
  • Loading branch information
3 people authored May 3, 2024
1 parent 992aa9d commit c7c4edd
Show file tree
Hide file tree
Showing 67 changed files with 3,057 additions and 91 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@
*node_modules/

# Medusa binary
medusa
medusa

# Medusa docs
docs/book
94 changes: 7 additions & 87 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,98 +17,18 @@ It provides parallelized fuzz testing of smart contracts through CLI, or its Go
- ✔️**Extensible low-level testing API** through events and hooks provided throughout the fuzzer, workers, and test chains.
-**Extensible high-level testing API** allowing for the addition of per-contract or global post call/event property tests with minimal effort.

## Installation
## Documentation

### Precompiled binaries
To learn more about how to install and use `medusa`, please refer to our [documentation](./docs/src/SUMMARY.md).

To use `medusa`, ensure you have:
For a better viewing experience, we recommend you install [mdbook](https://rust-lang.github.io/mdBook/guide/installation.html)
and then running the following steps from medusa's source directory:

- [crytic-compile](https://github.com/crytic/crytic-compile) (`pip3 install crytic-compile`)
- a suitable compilation framework (e.g. `solc`, `hardhat`) installed on your machine. We recommend [solc-select](https://github.com/crytic/solc-select) to quickly switch between Solidity compiler versions.

You can then fetch the latest binaries for your platform from our [GitHub Releases](https://github.com/crytic/medusa/releases) page.

### Building from source

#### Requirements

- You must have at least go 1.18 installed.
- [Windows only] The `go-ethereum` dependency may require [TDM-GCC](https://jmeubank.github.io/tdm-gcc/) to build.

#### Steps

- Clone the repository, then execute `go build` in the repository root.
- Go will automatically fetch all dependencies and build a binary for you in the same folder when completed.

## Usage

Although we recommend users run `medusa` in a configuration file driven format for more customizability, you can also run `medusa` through the CLI directly.
We provide instructions for both below.

We recommend you familiarize yourself with writing [assertion](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/basic/assertion-checking.md) and [property](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/introduction/how-to-test-a-property.md) tests for Echidna. `medusa` supports Echidna-like property testing and function optimization with config-defined function prefixes (default: `property_` and `optimize_`, respectively) and assertion testing using Solidity `assert(...)` statements.

### Command-line only

You can use the following command to run `medusa` against a contract:

```console
medusa fuzz --compilation-target contract.sol --target-contracts ContractName
```bash
cd docs
mdbook serve
```

Where:

- `--compilation-target` specifies the path `crytic-compile` should use to compile contracts
- `--target-contracts` specifies comma-separated names of contracts to be deployed for testing.

**Note:** Check out the [command-line interface](https://github.com/crytic/medusa/wiki/Command-Line-Interface) wiki page, or run `medusa --help` for more information.

### Configuration file driven

The preferred method to use medusa is to enter your project directory (hardhat directory, or directory with your contracts),
then execute the following command:

```console
medusa init
```

This will create a `medusa.json` in your current folder. There are two required fields that should be set correctly:

- Set your `"target"` under `"compilation"` to point to the file/directory which `crytic-compile` should use to build your contracts.
- Put the names of any contracts you wish to deploy and run tests against in the `"targetContracts"` field. This must be non-empty.

After you have a configuration in place, you can execute:

```console
medusa fuzz
```

This will use the `medusa.json` configuration in the current directory and begin the fuzzing campaign.

**Note:** Check out the [project configuration](https://github.com/crytic/medusa/wiki/Project-Configuration) wiki page, or run `medusa --help` for more information.

## Running Unit Tests

First, install [crytic-compile](https://github.com/crytic/crytic-compile), [solc-select](https://github.com/crytic/solc-select), and ensure you have `solc` (version >=0.8.7), and `hardhat` available on your system.

- From the root of the repository, invoke `go test -v ./...` on through command-line to run tests from all packages at or below the root.
- Or enter each package directory to run `go test -v .` to test the immediate package.
- Note: the `-v` parameter provides verbose output.
- Otherwise, use an IDE like [GoLand](https://www.jetbrains.com/go/) to visualize the tests and logically separate output.

## FAQs

**Why create `medusa` if Echidna is already working just fine?**

With `medusa`, we are exploring a different EVM implementation and language for our smart contract fuzzer. We believe that
experimenting with a new fuzzer provides us with the following benefits:

- Since `medusa` is written in Go, we believe that this will **lower the barrier of entry for external contributions**.
We have taken great care in thoroughly commenting our code so that it is easy for new contributors to get up-to-speed and start contributing!
- The use of Go allows us to build an API to hook into the various parts of the fuzzer to build custom testing methodologies. See the [API Overview (WIP)](<https://github.com/crytic/medusa/wiki/API-Overview-(WIP)>) section in the Wiki for more details.
- Our forked version of go-ethereum, [`medusa-geth`](https://github.com/crytic/medusa-geth), exhibits behavior that is closer to that of the EVM in production environments.
- We can take the lessons we learned while developing Echidna to create a fuzzer that is just as feature-rich but with additional capabilities to
create powerful and unique testing methodologies.

## Contributing

For information about how to contribute to this project, check out the [CONTRIBUTING](./CONTRIBUTING.md) guidelines.
Expand Down
17 changes: 17 additions & 0 deletions docs/book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[book]
title = "medusa"
authors = ["Trail of Bits"]
language = "en"
multilingual = false
src = "src"
description = "This repository, brought to you by Trail of Bits, contains the documentation files for the medusa fuzzer."

[output.html]
git-repository-url = "https://github.com/crytic/medusa"
edit-url-template = "https://github.com/crytic/medusa/edit/master/docs/{path}"
additional-css = ["src/static/custom.css"]
default-theme = "light"

[output.html.fold]
enable = true
level = 1
18 changes: 18 additions & 0 deletions docs/src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
![medusa_logo](./static/medusa_logo.png)

`medusa` is a cross-platform go-ethereum-based smart contract fuzzer inspired by Echidna. It provides parallelized fuzz
testing of smart contracts through CLI, or its Go API that allows custom user-extended testing methodology.

## Table of Contents

- [Getting Started](./getting_started/installation.md): Learn how to install `medusa` and how to set it up for your first project.
- [Project Configuration](./project_configuration/overview.md): Learn how to set up `medusa` for your project as well as
the vast number of configuration options that can be set up based on your project needs.
- [Command Line Interface](./cli/overview.md): Learn how to use `medusa`'s CLI.
- [Writing Tests](./testing/overview.md): Learn how to write tests with `medusa`
- [API (WIP)](./api/api_overview.md): Learn about `medusa`'s Go API that can be used to perform advanced testing
methodologies and extend `medusa`'s capabilities.
- Appendices
- [Cheatcodes](./cheatcodes/cheatcodes_overview.md): Learn about the various cheatcodes that are supported by `medusa`.
- [Console Logging](./console_logging.md): Learn about how to use `console.log` with `medusa`.
- [FAQ](./faq.md)
69 changes: 69 additions & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Summary

[Introduction](./README.md)

# Getting Started

- [Installation](./getting_started/installation.md)
- [First Steps](./getting_started/first_steps.md)

# Project Configuration

- [Configuration Overview](project_configuration/overview.md)
- [Fuzzing Configuration](project_configuration/fuzzing_config.md)
- [Testing Configuration](project_configuration/testing_config.md)
- [Chain Configuration](project_configuration/chain_config.md)
- [Compilation Configuration](project_configuration/compilation_config.md)
- [Logging Configuration](project_configuration/logging_config.md)

# Command Line Interface (CLI)

- [CLI Overview](./cli/overview.md)
- [init](./cli/init.md)
- [fuzz](./cli/fuzz.md)
- [completion](./cli/completion.md)

# Writing Tests

- [Testing Overview](./testing/overview.md)
- [The Fuzzing Lifecycle](./testing/fuzzing_lifecycle.md)
- [Types of Invariants](./testing/invariants.md)
- [Writing Function-Level Invariants](./testing/writing-function-level-invariants.md)
- [Writing System-Level Invariants (WIP)](./testing/writing-system-level-invariants.md)
- [Coverage Reports (WIP)](./testing/coverage_reports.md)

# API

- [API Overview (WIP)](api/api_overview.md)

# Appendices

- [Cheatcodes](cheatcodes/cheatcodes_overview.md)
- [warp](./cheatcodes/warp.md)
- [roll](./cheatcodes/roll.md)
- [fee](./cheatcodes/fee.md)
- [difficulty](./cheatcodes/difficulty.md)
- [chainId](./cheatcodes/chain_id.md)
- [store](./cheatcodes/store.md)
- [load](./cheatcodes/load.md)
- [etch](./cheatcodes/etch.md)
- [deal](./cheatcodes/deal.md)
- [snapshot](./cheatcodes/snapshot.md)
- [getNonce](./cheatcodes/get_nonce.md)
- [setNonce](./cheatcodes/set_nonce.md)
- [coinbase](./cheatcodes/coinbase.md)
- [prank](./cheatcodes/prank.md)
- [prankHere](./cheatcodes/prank_here.md)
- [ffi](./cheatcodes/ffi.md)
- [addr](./cheatcodes/addr.md)
- [sign](./cheatcodes/sign.md)
- [toString](./cheatcodes/to_string.md)
- [parseBytes](./cheatcodes/parse_bytes.md)
- [parseBytes32](./cheatcodes/parse_bytes32.md)
- [parseInt](./cheatcodes/parse_int.md)
- [parseUint](./cheatcodes/parse_uint.md)
- [parseBool](./cheatcodes/parse_bool.md)
- [parseAddress](./cheatcodes/parse_address.md)
- [Console Logging](./console_logging.md)

[FAQ](./faq.md)
16 changes: 16 additions & 0 deletions docs/src/advanced.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
> **Definition**: Stateful fuzzing is the process of maintaining EVM state across multiple fuzzed transactions.
Stateful fuzzing is an incredibly powerful feature because it allows medusa to test your system **end-to-end**. Let's
take, for example, a staking system where you have the ability to `deposit`, `stake`, `unstake`, and `withdraw`. Because
medusa can execute an array of transactions, medusa can call [`deposit`, `stake`, `unstake`, `withdraw`] inorder and test the
whole system in one fell swoop. It is very important to note that medusa was not _forced_ to call those functions in
sequence. Medusa, over time, will identify that calling deposit allows it to stake tokens and having a staked balance
allows it to unstake, and so on.

In contrast, having a call sequence length of 1 is called **stateless fuzzing**.

> **Definition**: Stateless fuzzing is the process of executing a single transaction before resetting the EVM state.
Stateless fuzzing is useful for arithmetic libraries or isolated functions where state does not need to be maintained
across transactions. Stateless fuzzing, although faster, is not useful for larger systems that have many code paths with
nuanced and complex invariants.
Loading

0 comments on commit c7c4edd

Please sign in to comment.