Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 9 additions & 24 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ written in Rust.
- `anvil`: local Ethereum development node
- `chisel`: Solidity REPL

The repository is a Cargo workspace. Core crates live under `crates/`, docs for
contributors live under `docs/dev/`, and Solidity fixtures and integration test
projects live under `testdata/`.
The repository is a Cargo workspace. Core crates live under `crates/`, Solidity
fixtures and integration test projects live under `testdata/`, and the
[developer documentation](docs/dev/README.md) defines documentation ownership
and indexes maintained cross-crate guides.

## Commands

Expand Down Expand Up @@ -46,8 +47,8 @@ Rust formatting uses nightly.

Foundry's EVM execution tooling is built around `revm`. Cheatcodes are calls to
the fixed cheatcode address and are dispatched through the cheatcode inspector.
Custom network behavior for `anvil`, `forge`, and `cast` is implemented through
the EVM networks crate.
For custom network work, follow the ownership, state-lifecycle, tool-dispatch,
and CI checklist in [`docs/dev/networks.md`](docs/dev/networks.md).

For symbolic execution work under `crates/evm/symbolic`, read
`crates/evm/symbolic/AGENTS.md` before editing.
Expand Down Expand Up @@ -93,25 +94,9 @@ replays persisted corpus entries and writes AFL `showmap`-style coverage files.

## CLI Output

Foundry CLIs follow a stdout/stderr contract:

- stdout is the command's machine-readable primary result
- stderr is for warnings, errors, progress, status text, prompts, and banners
- `--json` changes stdout format, not channel cleanliness
- `--quiet` suppresses diagnostics and progress, not the command result
- verbosity flags such as `-vvv` must not change stdout content

Use the `sh_*` macros from `foundry_common::io`:

- `sh_println!` / `sh_print!`: primary stdout result only
- `sh_status!`: status prose on stderr
- `sh_progress!`: progress on stderr
- `sh_warn!`: recoverable warnings on stderr
- `sh_err!`: errors on stderr
- `prompt!`: prompt on stderr and read from stdin

Do not use `println!`, `print!`, `eprintln!`, or `eprint!`; workspace clippy
configuration forbids them.
Follow [`docs/dev/output-channels.md`](docs/dev/output-channels.md), the canonical
stdout/stderr contract. Use the `foundry_common::io` `sh_*` and `prompt!` macros;
workspace Clippy configuration forbids direct `std::print*` and `std::eprint*`.

## Configuration

Expand Down
36 changes: 8 additions & 28 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,8 @@ make build
make pr
```

If you are working in VSCode, we recommend you install the [rust-analyzer](https://rust-analyzer.github.io/) extension, and use the following VSCode user settings:

```json
"editor.formatOnSave": true,
"rust-analyzer.rustfmt.extraArgs": ["+nightly"],
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer"
}
```
Contributor setup, editor configuration, validation commands, and maintained
implementation guides are indexed in the [developer documentation](docs/dev/README.md).

If you are working on a larger feature, we encourage you to open up a draft pull request, to make sure that other contributors are not duplicating work.

Expand All @@ -128,28 +121,15 @@ If you would like to use a debugger with breakpoints to debug a patch you might

#### Output channels (stdout vs. stderr)

Foundry CLIs follow a strict output-channel contract: **stdout is the command's
machine-readable result; stderr is everything else** (warnings, errors,
progress, status prose, prompts). When adding or modifying user-facing output,
read [`docs/dev/output-channels.md`](docs/dev/output-channels.md) and use the
`sh_*` macros from `foundry_common::io` (`sh_println!`, `sh_status!`,
`sh_progress!`, `sh_warn!`, `sh_err!`). A workspace-wide clippy
`disallowed-macros` lint (see [`clippy.toml`](clippy.toml)) forbids
`std::print*` and `std::eprint*`; use the `sh_*` macros instead.
User-facing output must follow the canonical
[stdout/stderr contract](docs/dev/output-channels.md). It also records the
required `foundry_common::io` macros and the current per-command migration state.

#### Adding tests

If the change being proposed alters code, it is either adding new functionality to Foundry, or fixing existing, broken functionality.
In both of these cases, the pull request should include one or more tests to ensure that Foundry does not regress
in the future.

Types of tests include:

- **Unit tests**: Functions which have very specific tasks should be unit tested.
- **Integration tests**: For general purpose, far reaching functionality, integration tests should be added.
The best way to add a new integration test is to look at existing ones and follow the style.

Tests that use forking must contain "fork" in their name.
Code changes should include focused unit or integration coverage. The
[developer documentation](docs/dev/README.md#setup-and-validation) is the
canonical entry point for test commands and repository-specific test rules.

#### Commits

Expand Down
7 changes: 6 additions & 1 deletion crates/evm/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
//! # foundry-evm-core
//!
//! Core EVM abstractions.
//! Generic execution, environment, fork, backend, and state abstractions shared by Foundry tools.
//!
//! [`evm::FoundryEvmNetwork`] binds an Alloy network to an [`evm::FoundryEvmFactory`]. The factory
//! owns the concrete execution types and constructs a Foundry-compatible EVM context, while
//! `foundry-evm-networks` owns runtime family selection. Keeping those responsibilities separate
//! allows one compiled binary to dispatch to different execution families at runtime.

#![cfg_attr(not(test), warn(unused_crate_dependencies))]
#![cfg_attr(docsrs, feature(doc_cfg))]
Expand Down
64 changes: 9 additions & 55 deletions crates/evm/networks/README.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,12 @@
# Custom EVM Networks
# Foundry EVM networks

The evm-networks crate defines custom network features that are shared across Foundry's tooling (`anvil`, `forge` and
`cast`). Currently, it supports custom precompiles, with planned support for custom transaction types.
This crate owns Foundry's runtime network-family selection and the network features that can be
shared across Forge, Cast, Anvil, Chisel, and the EVM backend. `NetworkConfigs` represents the active
execution profile; optional Cargo features only make additional profiles available to a binary.

## Adding a Custom Network
To add configuration support for a custom network (e.g. `my_network`), add a new field to the `NetworkConfigs` struct:
The crate does not instantiate an EVM. Concrete Alloy network and EVM factory types are associated
through `FoundryEvmNetwork` in `foundry-evm-core`.

```rust
/// Enable my custom network features.
#[arg(help_heading = "Networks", long)]
#[serde(default)]
pub my_network: bool,
```

This automatically enables:
- `my_network = true` in foundry.toml
- `--my-network` anvil CLI flag
```
Networks:
--my-network
Enable my custom network features

```

If you'd like network features to be enabled automatically based on the chain ID, update `NetworkConfigs::with_chain_id`:

```rust
impl NetworkConfigs {
pub fn with_chain_id(chain_id: u64) -> Self {
// Enable custom network features here
}
}
```

## Adding a custom precompile

- Create a module for your network-specific logic, e.g., `my_network/transfer`.
- Implement the precompile logic as a function that accepts a `PrecompileInput` containing execution context and hooks for
interacting with EVM state, and returns a `PrecompileResult`:

```rust
pub fn custom_precompile(
input: alloy_evm::precompiles::PrecompileInput<'_>
) -> revm::precompile::PrecompileResult {
// Your logic here
}
```

- Enable the precompile in the `NetworkConfigs` implementation by conditionally applying it to an address:

```rust
if self.my_network {
precompiles.apply_precompile(&MY_NETWORK_TRANSFER_ADDRESS, move |_| {
Some(my_network::transfer::custom_precompile())
});
}
```
See the [custom EVM integration guide](../../../docs/dev/networks.md) for ownership boundaries,
state-lifecycle requirements, tool coverage, and CI expectations. API details are published in the
[workspace Rustdoc](https://foundry-rs.github.io/foundry/foundry_evm_networks/).
12 changes: 11 additions & 1 deletion crates/evm/networks/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
//! # foundry-evm-networks
//!
//! Foundry EVM network configuration.
//! Runtime selection and shared configuration for Foundry's EVM network families.
//!
//! [`NetworkConfigs`] describes the active execution profile selected by configuration, CLI flags,
//! hardforks, or fork endpoint discovery. Cargo features only determine which optional
//! [`NetworkVariant`] values are compiled into a binary; they do not select a network at runtime.
//!
//! Concrete Alloy network and EVM factory types are associated by `FoundryEvmNetwork` in
//! `foundry-evm-core`. See the [custom EVM integration guide] for the cross-crate ownership and
//! state-lifecycle contract.
//!
//! [custom EVM integration guide]: https://github.com/foundry-rs/foundry/blob/master/docs/dev/networks.md

use crate::celo::transfer::{
CELO_TRANSFER_ADDRESS, CELO_TRANSFER_LABEL, PRECOMPILE_ID_CELO_TRANSFER,
Expand Down
119 changes: 51 additions & 68 deletions docs/dev/README.md
Original file line number Diff line number Diff line change
@@ -1,88 +1,71 @@
# Developer Docs
# Developer documentation

The Foundry project is organized as a regular [Cargo workspace][cargo-workspace].
These documents describe contributor workflows and invariants that span multiple Foundry crates.
They are not a second user manual or a manually maintained map of every workspace dependency.

## Installation requirements
## Documentation ownership

- [Rust](https://rustup.rs/)
- Make
Keep each fact in the source that owns it and link to that source elsewhere:

We use `cargo-nextest` as test runner (both locally and in the [CI](#ci)):
| Content | Canonical location |
| --- | --- |
| User-facing guides, configuration, and CLI workflows | [Foundry Book][foundry-book] |
| Crate and module APIs, invariants, and implementation details | Source Rustdoc, published as [Foundry Rustdoc][foundry-rustdoc] |
| Cross-crate contributor workflows | `docs/dev/` or [`CONTRIBUTING.md`](../../CONTRIBUTING.md) |
| Agent-only repository instructions | [`AGENTS.md`](../../AGENTS.md) |
| Release-facing changes | [Changelog fragments](../../.changelog/README.md) |

- [Nextest](https://nexte.st/docs/installation/pre-built-binaries/#with-cargo-binstall)
Do not copy generated CLI reference text or crate dependency lists into `docs/dev`. Update CLI help
or Rustdoc at the source, then link to the generated documentation.

## Recommended
## Setup and validation

If you are working in VSCode, we recommend you install the [rust-analyzer](https://rust-analyzer.github.io/) extension, and use the following VSCode user settings:

```json
"editor.formatOnSave": true,
"rust-analyzer.rustfmt.extraArgs": ["+nightly"],
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer"
}
```

Note that we use Rust's latest `nightly` for formatting. If you see `;` being inserted by your code editor it is a good indication you are on `stable`.

## Getting started

Build the project.
Install [Rust][rust], Make, and [cargo-nextest][nextest]. Foundry uses the stable toolchain for
normal builds and the latest nightly toolchain for formatting and Clippy.

```sh
$ make build
make build
make test
make pr
```

Run all tests.

```sh
$ make test
```

Run all tests and linters in preparation for a PR.

```sh
$ make pr
```

## Contents

- [Architecture](./architecture.md)
- [Cheatcodes](./cheatcodes.md)
- [Debugging](./debugging.md)
- [Scripting](./scripting.md)
- [Custom Network Features](./networks.md)

_Note: This is incomplete and possibly outdated_

## Getting in Touch

See also [Getting Help](../../README.md#getting-help)

## Issue Labels

Whenever a ticket is initially opened a [`T-needs-triage`](https://github.com/foundry-rs/foundry/issues?q=is%3Aissue+is%3Aopen+label%3AT-needs-triage) label is assigned. This means that a member has yet to correctly label it.

If this is your first time contributing have a look at our [`first-issue`](https://github.com/foundry-rs/foundry/issues?q=is%3Aissue+is%3Aopen+label%3A%22first+issue%22) tickets. These are tickets we think are a good way to get familiar with the codebase.

We classify the tickets in two major categories: [`T-feature`](https://github.com/foundry-rs/foundry/issues?q=is%3Aissue+is%3Aopen+label%3AT-feature) and [`T-bug`](https://github.com/foundry-rs/foundry/issues?q=is%3Aissue+is%3Aopen+label%3AT-bug). Additional labels are usually applied to help categorize the ticket for future reference.
Use focused unit tests for local logic and integration tests for user-visible workflows. Tests that
use forking must contain `fork` in their name. Forge and Cast CLI tests live under
`crates/forge/tests/cli/` and `crates/cast/tests/cli/`; shared integration fixtures live in
`crates/test-utils`, and Solidity fixtures live under `testdata/`.

We also make use of [`T-meta`](https://github.com/foundry-rs/foundry/issues?q=is%3Aissue+is%3Aopen+label%3AT-meta) aggregation tickets. These tickets are tickets to collect related features and bugs.
## Maintained guides

We also have [`T-discuss`](https://github.com/foundry-rs/foundry/issues?q=is%3Aissue+is%3Aopen+label%3AT-to-discuss) tickets that require further discussion before proceeding on an implementation. Feel free to jump into the conversation!
- [Cheatcodes](./cheatcodes.md) explains cheatcode generation, dispatch, and implementation.
- [Debugging](./debugging.md) collects contributor debugging techniques.
- [Lint rules](./lintrules.md) covers the lint registry, UI fixtures, and documentation contract.
- [Custom EVM integrations](./networks.md) describes network selection, execution ownership,
state lifecycles, tool dispatch, and CI coverage.
- [Output channels](./output-channels.md) defines the stdout/stderr contract for Foundry commands.
- [Scripting](./scripting.md) documents the internal script execution and broadcast pipeline.
- [Showmap corpus replay](./showmap.md) documents the persisted-corpus coverage workflow and file
format.

## CI
## Updating documentation

We use GitHub Actions for continuous integration (CI).
When a change affects users, update the [Foundry Book][foundry-book] and the source CLI help where
applicable. When it changes a crate or module contract, update Rustdoc next to the implementation.
Add or update a guide here only when contributors need a cross-crate workflow or invariant that does
not have a single source owner.

We use [cargo-nextest][nextest] as the test runner.
Every maintained guide must be linked from this index. Prefer links to canonical documentation over
duplicated instructions so updates cannot drift independently.

If `make test` passes locally, that's a good sign that CI will be green as well.
## CI and release features

## Release Features
CI runs tests through cargo-nextest. Nightly and stable release builds derive their enabled
functionality from `RUST_FEATURES` in `.github/workflows/release.yml` and
`.github/workflows/docker-publish.yml`. Keep those lists aligned with the default `FEATURES` in the
root `Makefile` so published binaries expose the same surface as local release builds.

Nightly/stable release builds derive their enabled functionality from the shared `RUST_FEATURES` environment variable in `.github/workflows/release.yml` and `.github/workflows/docker-publish.yml`. Keep that list aligned with the default `FEATURES` value in the root `Makefile` so published artifacts expose the same CLI surface area (wallet backends, allocators, tracers, etc.) as local builds.
For contribution policy and support channels, see [`CONTRIBUTING.md`](../../CONTRIBUTING.md).

[foundry-book]: https://book.getfoundry.sh
[cargo-workspace]: https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html
[nextest]: https://nexte.st/
[foundry-book]: https://getfoundry.sh
[foundry-rustdoc]: https://foundry-rs.github.io/foundry/
[nextest]: https://nexte.st/docs/installation/pre-built-binaries/#with-cargo-binstall
[rust]: https://rustup.rs/
18 changes: 0 additions & 18 deletions docs/dev/architecture.md

This file was deleted.

Loading
Loading