Skip to content
Draft
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
53 changes: 53 additions & 0 deletions .github/workflows/ev_deployer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: EV Deployer CI

on:
push:
paths:
- 'contracts/src/**'
- 'contracts/foundry.toml'
- 'bin/ev-deployer/**'
pull_request:
paths:
- 'contracts/src/**'
- 'contracts/foundry.toml'
- 'bin/ev-deployer/**'
workflow_dispatch:

env:
CARGO_TERM_COLOR: always

jobs:
verify-bytecodes:
name: EV Deployer bytecode verification
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
with:
submodules: recursive

- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1

- name: Run bytecode verification tests
run: cargo test -p ev-deployer -- --ignored --test-threads=1

unit-tests:
name: EV Deployer unit tests
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6

- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true

- name: Run unit tests
run: cargo test -p ev-deployer
81 changes: 72 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[workspace]
resolver = "2"
members = [
"bin/ev-deployer",
"bin/ev-dev",
"bin/ev-reth",
"crates/common",
Expand Down
23 changes: 23 additions & 0 deletions bin/ev-deployer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "ev-deployer"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
authors.workspace = true

[dependencies]
alloy-primitives = { workspace = true, features = ["serde"] }
clap = { workspace = true, features = ["derive", "env"] }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
toml = "0.8"
eyre = { workspace = true }

[dev-dependencies]
tempfile = { workspace = true }

[lints]
workspace = true
134 changes: 134 additions & 0 deletions bin/ev-deployer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# EV Deployer

CLI tool for generating genesis alloc entries for ev-reth contracts. It reads a declarative TOML config and produces the JSON needed to embed contracts into a chain's genesis state.

## Building

```bash
just build-deployer
```

The binary is output to `target/release/ev-deployer`.

## Configuration

EV Deployer uses a TOML config file to define what contracts to include and how to configure them. See [`examples/devnet.toml`](examples/devnet.toml) for a complete example.

```toml
[chain]
chain_id = 1234

[contracts.admin_proxy]
address = "0x000000000000000000000000000000000000Ad00"
owner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"

[contracts.fee_vault]
address = "0x000000000000000000000000000000000000FE00"
owner = "0x000000000000000000000000000000000000Ad00"
destination_domain = 0
recipient_address = "0x0000000000000000000000000000000000000000000000000000000000000000"
minimum_amount = 0
call_fee = 0
bridge_share_bps = 10000
other_recipient = "0x0000000000000000000000000000000000000000"
hyp_native_minter = "0x0000000000000000000000000000000000000000"
```

Both contracts are optional — include only the sections you need.

### Config reference

#### `[chain]`

| Field | Type | Description |
|------------|------|-------------|
| `chain_id` | u64 | Chain ID |

#### `[contracts.admin_proxy]`

| Field | Type | Description |
|-----------|---------|---------------------------|
| `address` | address | Address to deploy at |
| `owner` | address | Owner (must not be zero) |

#### `[contracts.fee_vault]`

| Field | Type | Default | Description |
|----------------------|---------|---------|------------------------------------------------|
| `address` | address | — | Address to deploy at |
| `owner` | address | — | Owner (must not be zero) |
| `destination_domain` | u32 | 0 | Hyperlane destination domain |
| `recipient_address` | bytes32 | 0x0…0 | Hyperlane recipient |
| `minimum_amount` | u64 | 0 | Minimum amount for bridging |
| `call_fee` | u64 | 0 | Fee for sendToCelestia |
| `bridge_share_bps` | u64 | 0 | Bridge share in basis points (0–10000). 0 maps to 10000 |
| `other_recipient` | address | 0x0…0 | Split accounting recipient |
| `hyp_native_minter` | address | 0x0…0 | HypNativeMinter address |

## Usage

### Generate genesis alloc

Print alloc JSON to stdout:

```bash
ev-deployer genesis --config deploy.toml
```

Write to a file:

```bash
ev-deployer genesis --config deploy.toml --output alloc.json
```

### Merge into an existing genesis file

Insert the generated entries into an existing `genesis.json`. This modifies the `alloc` field in-place and writes the full result:

```bash
ev-deployer genesis --config deploy.toml --merge-into genesis.json --output genesis-out.json
```

If an address already exists in the genesis, the command fails. Use `--force` to overwrite:

```bash
ev-deployer genesis --config deploy.toml --merge-into genesis.json --output genesis-out.json --force
```

### Export address manifest

Write a JSON mapping of contract names to their configured addresses:

```bash
ev-deployer genesis --config deploy.toml --addresses-out addresses.json
```

Output:

```json
{
"admin_proxy": "0x000000000000000000000000000000000000Ad00",
"fee_vault": "0x000000000000000000000000000000000000FE00"
}
```

### Look up a contract address

```bash
ev-deployer compute-address --config deploy.toml --contract admin_proxy
```

## Contracts

| Contract | Description |
|----------------|-----------------------------------------------------|
| `admin_proxy` | Proxy contract with owner-based access control |
| `fee_vault` | Fee vault with Hyperlane bridge integration |

Runtime bytecodes are embedded in the binary — no external toolchain is needed at deploy time.

## Testing

```bash
just test-deployer
```
Loading
Loading