Skip to content
Open
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
61 changes: 61 additions & 0 deletions .github/workflows/ci-quantum.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: CI Quantum

permissions: {}

on:
push:
branches: [master]
pull_request:
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

env:
CARGO_TERM_COLOR: always
RUSTC_WRAPPER: "sccache"
QUANTUM_FOUNDRY_BASE_COMMIT: "f1abb2ca347187bb6dea8c3881ca44ce50aab1e7"
QUANTUM_HARNESS_COMMIT: "8f3612c60f9fa66ea3a09eab99a2e0802f373673"

jobs:
quantum-check:
runs-on: depot-ubuntu-latest
timeout-minutes: 60
permissions:
contents: read
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
with:
toolchain: nightly
components: rustfmt, clippy

- uses: mozilla-actions/sccache-action@7d986dd989559c6ecdb630a3fd2557667be217ad # v0.0.9
- uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # v2

- name: Format check
run: cargo fmt --all --check

- name: Clippy
run: cargo clippy --workspace --all-targets -- -D warnings

# Quantum-scoped package tests lock the adapter, envelope, and lifecycle
# contracts. The broader `cargo test --workspace` target is intentionally
# not gated in CI because it inherits upstream Foundry tests that hit
# external networks (Etherscan, live mainnet RPC, flaky fork endpoints)
# and fail in isolated CI environments regardless of this fork's changes.
- name: Quantum package tests
run: cargo test -p foundry-common -p foundry-primitives -p foundry-cli -p cast

# Targeted Quantum regression: pinned golden fixture and composite RLP envelope.
# Multiple filters must follow `--` (cargo test accepts only a single
# positional TESTNAME before `--`; libtest then applies all post-`--`
# filters as an OR under `--exact`).
- name: Quantum fixture regression
run: |
cargo test -p foundry-common --lib -- --exact \
transactions::quantum::tests::generated_fixture_matches_checked_in_phase0_example \
transactions::quantum::tests::detached_p256_cosigner_is_attached_to_composite_signature
138 changes: 0 additions & 138 deletions .github/workflows/ci-tempo.yml

This file was deleted.

8 changes: 4 additions & 4 deletions Cargo.lock

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

99 changes: 99 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,102 @@
<br>
<br>

<p align="center">
<a href="https://quantum.systems">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://quantum.systems/images/logo-white.svg">
<img alt="tempo combomark" src="https://quantum.systems/images/logo-white.svg" width="auto" height="120">
</picture>
</a>
</p>

<br>
<br>

# Quantum Foundry

Quantum is a post-quantum-ready EVM execution environment with a dedicated native transaction type (`0x7A`), explicit account lanes, and an ML-DSA-44 primary signer with optional detached classical cosigners.

`Quantum Foundry` is a custom fork of [Foundry](https://github.com/foundry-rs/foundry) that integrates Quantum's native envelope, KeyVault lifecycle UX, and detached-cosigner contract directly into the familiar Foundry developer workflow.

This fork is a drop-in replacement for upstream Foundry while Quantum-specific features are being stabilized; it tracks Foundry commit `f1abb2ca347187bb6dea8c3881ca44ce50aab1e7` and the Quantum harness commit `8f3612c60f9fa66ea3a09eab99a2e0802f373673`. See [`docs/dev/quantum-phase0-implementation-note.md`](./docs/dev/quantum-phase0-implementation-note.md) for the frozen RPC, signer, and ABI contract.

## Installation

```sh
curl -L https://raw.githubusercontent.com/multivmlabs/quantum-foundry/HEAD/foundryup/install | bash
foundryup --network quantum
```

This installs the Quantum-enabled `forge`, `cast`, `anvil`, and `chisel` from this fork's GitHub Releases into `~/.foundry-quantum/bin/`. The separate directory means quantum-foundry coexists with an existing upstream Foundry install at `~/.foundry/` — neither installer overwrites the other's binaries. If both are on your `PATH`, the one listed earlier wins for commands like `forge` and `cast`.

<details>
<summary>Building from source (contributors and unsupported platforms)</summary>

```sh
cargo build --release -p forge -p cast -p anvil -p chisel
```

The `target/release` binaries are drop-in replacements for upstream `forge`, `cast`, `anvil`, and `chisel`.

</details>

## Devnet

Quantum's public devnet is available for early testing. **Note: the devnet is unstable — state may be wiped, chain ID may change, and downtime should be expected. A public testnet is targeted for mid-2026.**

| Property | Value |
| ------------------ | ------------------------------------- |
| **Network Name** | Quantum Devnet |
| **Chain ID** | `1337` |
| **HTTP URL** | `https://devnet2.rpc.quantum.systems` |
| **Block Explorer** | `https://quantumscan.org/` |

Example:

```sh
cast block-number --rpc-url https://devnet2.rpc.quantum.systems
```

## Changeset

Key Quantum extensions on top of upstream Foundry:

- In `cast send`:
- `--quantum`: opt into the explicit Quantum adapter path (selection is explicit in v1, not inferred from chain ID).
- `--quantum.sender <ADDRESS>`: explicit Quantum account-lane address. Quantum writes never auto-derive the sender from the signing key.
- `--quantum.key-id <KEY_ID>`: account-lane key ID; defaults to `0` for ordinary v1 flows.
- `--quantum.primary-seed-file <PATH>`: canonical v1 ML-DSA-44 signer seed (single 32-byte hex seed, with or without `0x`).
- `--quantum.cosigner-artifact <PATH>`: optional detached v1 cosigner artifact JSON; schemes `p256` and `ecdsa` are supported and the artifact's `signing_hash` must match the fork-computed Quantum signing hash byte-for-byte.
- KeyVault lifecycle selectors (`bootstrapKey`, `addKey`, `removeKey`, `updateKeyAuth`) are rejected by the `cast send` pre-build guard and must be submitted through `cast quantum` instead.

- In `cast quantum` (new subcommand group for KeyVault lifecycle UX):
- `cast quantum bootstrap`: primary-only `bootstrapKey()` through the shared `0x7A` signing pipeline.
- `cast quantum add-key`: `addKey(...)` with `--auth-key-id` (signer lane) distinct from `--target-key-id` (entry being added) so the two lanes cannot be confused.
- `cast quantum remove-key`: `removeKey(uint32)`.
- `cast quantum update-key-auth`: `updateKeyAuth(...)` with the same auth-lane / target-lane separation.
- All lifecycle writes auto-apply the fixed `QUANTUM_LIFECYCLE_GAS_FLOOR` (2,100,000) because validator-published transient state cannot be reproduced by `eth_estimateGas`.

- In `cast call`:
- Fails closed on KeyVault lifecycle selectors with the frozen `QUANTUM_CALL_LIFECYCLE_REJECTION_MESSAGE`, preserving ordinary read paths on standard RPC simulation.

- In `forge create`:
- `--quantum` and the `--quantum.*` flags route CREATE through the shared Quantum adapter with the same explicit sender / key-id / seed / cosigner contract as `cast send`.

- In `forge script`:
- Scripted broadcast routes through the shared Quantum adapter for supported write shapes and fails closed on unsupported Quantum script shapes with a stable rejection message.

- Additionally:
- A shared `QuantumWriteRequestV1` write contract with fail-closed v1 validation: `nonce_key` must be `0`, multi-call bundles are rejected, and lifecycle-selector misuse is caught before signing.
- Detached cosigner artifact v1 (`version = 1`, `scheme`, `signing_hash`, `public_key`, `signature`) with composite-signature RLP layout using scheme bytes `0x01` (ML-DSA), `0x02` (P256), `0x03` (ECDSA).
- KeyVault lifecycle calldata builders derived from a shared `sol!` interface whose selectors are asserted byte-for-byte against the Phase 0 frozen constants.
- A pinned golden fixture (`testdata/fixtures/quantum/phase0/raw-send-primary.json`) that locks the raw `0x7A` envelope bytes end-to-end.

See [`docs/dev/quantum-adapter-touchpoints.md`](./docs/dev/quantum-adapter-touchpoints.md) for the full manifest of Quantum-modified files.

<br>
<br>

<div align="center">
<img src=".github/assets/banner.png" alt="Foundry banner" />

Expand Down
Loading
Loading