Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
138 commits
Select commit Hold shift + click to select a range
e8d1cac
feat(contracts): add BoundlessRouter and verifier seam interfaces
jonastheis May 8, 2026
d3d8643
feat(contracts): add R0 verifier and assessor adapters for the router
jonastheis May 8, 2026
4828781
refactor(contracts): add universal `prover` arg to assessor and joint…
jonastheis May 8, 2026
5409644
refactor(contracts): rewrite BoundlessMarket to dispatch via Boundles…
jonastheis May 8, 2026
2d9bba1
feat(contracts): add separate deploy and manage scripts for Boundless…
jonastheis May 8, 2026
8db04de
chore(boundless-market): regenerate Solidity artifacts and bytecode
jonastheis May 11, 2026
5c912f9
refactor(contracts): introduce SlimRequest and unify assessor seam
jonastheis May 13, 2026
5dcb545
feat(contracts): add OnChainAssessor adapter
jonastheis May 13, 2026
252c732
refactor(contracts): rename SubBatch to FulfillmentBatch and wrap pri…
jonastheis May 15, 2026
eb27658
test(contracts): split router benches into BenchBase + Adapter + Router
jonastheis May 15, 2026
9234d53
perf(contracts): reduce BoundlessRouter.verifyBatch dispatch overhead
jonastheis May 15, 2026
5a354c5
perf(contracts): cache same-selector entry lookup; cleanup helpers
jonastheis May 15, 2026
8d0fdca
perf(contracts): forward assessor calldata via tail-call helper
jonastheis May 18, 2026
b606153
build(contracts): compile router + adapters with optimizer_runs=1_000…
jonastheis May 18, 2026
bf22a8b
test(contracts): separate bench measurements from sanity tests
jonastheis May 18, 2026
cd3866d
test(contracts): scaffold BoundlessMarket.t.sol for new architecture
jonastheis May 18, 2026
aed2e16
test(contracts): port account + lock tests in BoundlessMarket.t.sol
jonastheis May 18, 2026
178a0b2
fix(contracts): domain-bind requestDigest before lock-binding check
jonastheis May 18, 2026
8c83bab
test(contracts): make bench fixtures match real-traffic calldata
jonastheis May 18, 2026
75be369
test(contracts): port fulfill + slash tests in BoundlessMarket.t.sol
jonastheis May 19, 2026
9dc5b0f
test(contracts): port batch + smart-contract sig + callback tests
jonastheis May 19, 2026
812faa2
test(contracts): port submitRoot tests in BoundlessMarket.t.sol
jonastheis May 19, 2026
8458cdc
test(contracts): e2e the R0 proof-based assessor adapter
jonastheis May 19, 2026
cf60a12
test(contracts): port BoundlessMarketUpgradeTest
jonastheis May 19, 2026
b9bd96c
test(contracts): port BoundlessMarketBench through R0 adapter
jonastheis May 19, 2026
5d9de06
refactor(router): pass FulfillmentBatch struct through verifyBatch / …
jonastheis May 19, 2026
60048d2
refactor(router): pass full per-fill payload through verifyJoint
jonastheis May 20, 2026
b9ff55e
chore(contracts): forge fmt + regenerate Rust artifacts, extract IBou…
jonastheis May 20, 2026
e1c5da1
chore(contracts): remove OnChainAssessor from this PR
jonastheis May 20, 2026
fae0737
Revert "chore(contracts): remove OnChainAssessor from this PR"
jonastheis May 20, 2026
228d4e5
test(contracts): add router test base + registry suite + mocks
jonastheis May 20, 2026
8ac1f04
test(contracts): add router dispatch suite
jonastheis May 21, 2026
a9b554d
feat(router): refuse removeClass while entries still live
jonastheis May 21, 2026
90e0bf4
docs(router): correct verifyBatch isolation guarantee and pin behavior
jonastheis May 22, 2026
eefe5a5
feat(router): reject addClass with zero defaultGasLimit
jonastheis May 22, 2026
47ddf2f
docs(router): consolidate tail-call ABI invariant at the helper
jonastheis May 22, 2026
c593280
test(contracts): cover SlimRequest binding revert per EIP-712 field
jonastheis May 22, 2026
e3b4ce0
test(contracts): pin slim-id swap rejection in mutation coverage
jonastheis May 22, 2026
994a90a
test(contracts): tighten market suite
jonastheis May 22, 2026
a561a9f
test(contracts): exercise R0 assessor image-id rotation end-to-end
jonastheis May 22, 2026
0d0189e
test(contracts): unit-cover R0 assessor adapter independent of market
jonastheis May 22, 2026
607c867
test(contracts): cover multi-batch fulfill across heterogeneous adapters
jonastheis May 22, 2026
c6122e1
style(contracts): apply forge fmt
jonastheis May 22, 2026
04dfa3e
chore(contracts): clean up TODOs in router/bench tests
jonastheis May 22, 2026
900b85a
Merge branch 'jonas/router-decoupling' into jonas/onchain-assessor
jonastheis May 26, 2026
cb01164
fix(contracts): align on-chain journal-hash convention and bind callb…
jonastheis May 26, 2026
616fcd0
refactor(contracts): publicize OnChainAssessor typehash and use Messa…
jonastheis May 26, 2026
8dd29fb
test(contracts): end-to-end fulfill paths through OnChainAssessor
jonastheis May 26, 2026
a8fa019
test(contracts): expand OnChainAssessor unit suite
jonastheis May 26, 2026
3323fa0
test(contracts): align bench fixture journal hash with canonical conv…
jonastheis May 26, 2026
e2fedc7
perf(contracts): share submitMerkleRoot call across submitRoot* wrapp…
jonastheis May 28, 2026
894e8ba
refactor(contracts): consolidate OnChainAssessor reconstruction guard
jonastheis May 28, 2026
789075e
chore(contracts): import main's BoundlessMarket sources into legacy/
jonastheis May 28, 2026
2e2b127
test(contracts): port main's BoundlessMarket suite into test/legacy/
jonastheis May 28, 2026
6a85429
chore(contracts): verify legacy/ bytecode parity against deployed OLD…
jonastheis May 28, 2026
10e4380
chore(contracts): enforce storage layout interop between src/ and src…
jonastheis May 28, 2026
9015ff0
feat(contracts): forward legacy ABI to a configurable impl via fallback
jonastheis May 28, 2026
d90b32c
test(contracts): exercise legacy ABI against the new market via fallback
jonastheis May 28, 2026
cd1d6a2
test(contracts): pin cross-ABI invariants in a focused suite
jonastheis May 28, 2026
082190b
chore(contracts): wire legacy impl into Deploy.s.sol and unbreak depl…
jonastheis May 29, 2026
65f6640
docs(contracts): document the legacy/ freeze policy and provenance
jonastheis May 29, 2026
d78afe4
Merge remote-tracking branch 'origin/main' into jonas/router-decoupling
jonastheis Jun 4, 2026
c78588c
refactor(boundless-market): migrate SDK to batched FulfillmentBatch API
jonastheis Jun 4, 2026
fd59ffd
refactor(backend): drop Fulfillment id/requestDigest, source assessor…
jonastheis Jun 4, 2026
e860d5a
refactor(broker): build batched fulfillment payload, source assessor …
jonastheis Jun 4, 2026
54ada9f
refactor(cli): batched fulfill payload, assessor selector flag, deriv…
jonastheis Jun 4, 2026
cbbcfd3
fix(contracts): carry requestDigest in ProofDelivered; adapt indexer …
jonastheis Jun 4, 2026
21e34b3
test(harness): deploy BoundlessRouter in the Rust test harness; migra…
jonastheis Jun 4, 2026
93987d8
refactor(contracts): forward legacy ABI via OpenZeppelin Proxy
jonastheis Jun 5, 2026
3cbef17
refactor(contracts): de-duplicate legacy ABI test suites via inheritance
jonastheis Jun 5, 2026
abab0d5
feat(deploy): deploy the BoundlessRouter via its own scripts in localnet
jonastheis Jun 5, 2026
3ca634b
test(contracts): drop the :v2 bench snapshot suffix and fix the comment
jonastheis Jun 5, 2026
4891357
docs(contracts): reformat batched-API NatSpec to avoid rustdoc doctests
jonastheis Jun 5, 2026
9313bc8
fix(cli,broker): prove the assessor with the deployed image in tests
jonastheis Jun 5, 2026
0324555
cargo fmt
jonastheis Jun 5, 2026
808383c
fix(test-utils,broker): complete BoundlessRouter test harness wiring
jonastheis Jun 5, 2026
1008a8e
Merge branch 'jonas/router-decoupling' into jonas/onchain-assessor
jonastheis Jun 5, 2026
3db3efe
Merge branch 'jonas/router-decoupling' into jonas/market-legacy-fallback
jonastheis Jun 5, 2026
e9e8434
fix(contracts): reconcile onchain-assessor branch with router-decoupl…
jonastheis Jun 5, 2026
64050e5
forge fmt
jonastheis Jun 8, 2026
d1f79be
fix(test-utils): pass legacyImpl to the 3-arg BoundlessMarket constru…
jonastheis Jun 8, 2026
9cb7f66
style(contracts): satisfy dprint and forge fmt checks
jonastheis Jun 8, 2026
0d06344
fix(contracts): resolve legacyImpl in manage deploy/upgrade scripts
jonastheis Jun 8, 2026
ee3c0f5
test(contracts): migrate deployment-test to the new batched ABI
jonastheis Jun 8, 2026
b343ed6
test(contracts): stub the legacy impl in the BoundlessMarket harness
jonastheis Jun 8, 2026
c248f56
test(contracts): refresh market snapshots after batched-ABI migration
jonastheis Jun 8, 2026
62fc00a
Merge remote-tracking branch 'origin/jonas/onchain-assessor' into jon…
jonastheis Jun 8, 2026
918bf32
feat(broker): select the assessor per batch from a router registry sn…
jonastheis Jun 11, 2026
d989736
test(broker): assert the assessor seal selector in e2e and cover the …
jonastheis Jun 11, 2026
b960648
fix(localnet): run the deploy natively and self-heal a stale collater…
jonastheis Jun 11, 2026
f914de4
fix(bench): drop the removed assessor_selector config field
jonastheis Jun 11, 2026
1b252e0
chore: dprint-format the localnet skill
jonastheis Jun 11, 2026
3b7f4f6
fix(contracts): qualify the upgrade reference and stop reference-cach…
jonastheis Jun 12, 2026
ab40a22
fix(router): raise the verifier-class gas cap to cover real proof ver…
jonastheis Jun 12, 2026
cecfb74
fix(examples): compile the router with via-ir and honor Bento/Bonsai …
jonastheis Jun 12, 2026
30efb49
feat(deploy): carry the legacy assessor imageUrl from the market bein…
jonastheis Jun 12, 2026
dcff67c
fix(deploy): survive in-place upgrades and rollbacks of legacy-impl p…
jonastheis Jun 12, 2026
156d081
feat(router): one class per proof type and an idempotent bootstrap
jonastheis Jun 12, 2026
c812bde
feat(sdk): reject class-signed blake3-groth16 requests
jonastheis Jun 15, 2026
a8cf239
feat(examples): submit_echo accepts --selectors for per-selector requ…
jonastheis Jun 15, 2026
1437604
refactor(deploy): resolve router script inputs from deployment.toml
jonastheis Jun 15, 2026
2036e55
fix(sdk): move requirements_layer tests to end of file
jonastheis Jun 15, 2026
7b18191
refactor(backend): accept set-inclusion pins, make the class pick exp…
jonastheis Jun 15, 2026
3eabe63
fix(examples): handle journal-less fulfillments in submit_echo
jonastheis Jun 15, 2026
d49042c
feat(market): keep ProofDelivered on the legacy ABI for pre-router cl…
jonastheis Jun 16, 2026
5c1ecac
Revert "feat(sdk): reject class-signed blake3-groth16 requests"
jonastheis Jun 16, 2026
41f5089
feat(sdk): support class-signed blake3-groth16 requests
jonastheis Jun 16, 2026
47feca4
Base Sepolia deployment
jonastheis Jun 16, 2026
872aee7
fix(deploy): emit upgradeToAndCall, not upgradeTo, in the Safe upgrad…
jonastheis Jun 16, 2026
fc78c8d
fix(deploy): bootstrap set-inclusion/assessor against the router-regi…
jonastheis Jun 16, 2026
b04705a
Base Sepolia deployment
jonastheis Jun 16, 2026
e2bc0cc
feat(market): keep ProofDelivered on the legacy ABI for pre-router cl…
jonastheis Jun 16, 2026
07f9407
feat(contracts): build the Shanghai market variant from the shared sr…
jonastheis Jun 18, 2026
48ef26c
feat(contracts): freeze the Taiko legacy market for the in-place upgrade
jonastheis Jun 18, 2026
f07646e
refactor(contracts): share scripts/tests for the shanghai profile and…
jonastheis Jun 18, 2026
00369e7
ci(contracts): gate the Taiko (shanghai) legacy bytecode + storage-la…
jonastheis Jun 19, 2026
ec41529
fix(contracts): make the shanghai port pass CI (license paths + SDK a…
jonastheis Jun 19, 2026
16024cd
feat(deploy): emit router bootstrap as a Safe batch so the deployer i…
jonastheis Jun 21, 2026
00c31e1
Merge remote-tracking branch 'origin/jonas/adopt-router-in-broker' in…
jonastheis Jun 22, 2026
9bfcb77
ci(contracts): run the shanghai contract suite in the parity gate
jonastheis Jun 22, 2026
e160964
wip(merge): land #2040 (adopt-router-in-broker) onto main (#2039 Zkvm…
jonastheis Jul 2, 2026
5cab55b
fix(contracts): file-qualify the upgrade-safety reference to disambig…
jonastheis Jul 1, 2026
f2e8dd4
fix(contracts): use full source-path FQN for the upgrade-safety refer…
jonastheis Jul 1, 2026
7c55097
refactor(broker): resolve assessor group before claiming open-batch o…
jonastheis Jul 2, 2026
3c992ca
Merge remote-tracking branch 'origin/jonas/adopt-router-in-broker' in…
jonastheis Jul 2, 2026
48661c7
Merge remote-tracking branch 'origin/main' into jonas/router-shanghai…
jonastheis Jul 2, 2026
7375dfd
refactor(contracts): remove unused MismatchedRequestId error and Upgr…
jonastheis Jul 6, 2026
54496b7
fix(contracts): forbid permissionless assessor classes in the router …
jonastheis Jul 6, 2026
85f7bbb
fix(contracts): guard open-path fulfillment against copied-proof fron…
jonastheis Jul 6, 2026
70331a2
fix(contracts): align RequestIsExpired error encoding with its declar…
jonastheis Jul 6, 2026
9854e43
Merge remote-tracking branch 'origin/main' into audit/settlement-veri…
jonastheis Jul 6, 2026
033390c
fix test
jonastheis Jul 6, 2026
d23f5d5
feat(market): commit-then-reveal for open-path fulfillment (#2052)
jonastheis Jul 6, 2026
ebd8c76
Merge remote-tracking branch 'origin/audit/settlement-verification-de…
jonastheis Jul 6, 2026
ae1fe5c
test(indexer): fulfill lock-expired request via the open path (#2052)
jonastheis Jul 6, 2026
9f0ffbd
fix(contracts): port commit-then-reveal open-path guard to shanghai m…
jonastheis Jul 6, 2026
23b58af
Merge remote-tracking branch 'origin/audit/settlement-verification-de…
jonastheis Jul 6, 2026
75c2f28
Merge remote-tracking branch 'origin/main' into jonas/router-shanghai…
jonastheis Jul 7, 2026
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
13 changes: 13 additions & 0 deletions .github/workflows/contracts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ jobs:
filters: |
src:
- 'contracts/src/**'
- 'contracts/shanghai/**'
foundry:
- 'foundry.toml'
test:
Expand Down Expand Up @@ -104,6 +105,18 @@ jobs:
- name: Verify storage layout interop between src/ and src/legacy/
run: python3 contracts/scripts/verify-storage-layout.py

- name: forge build (shanghai profile)
run: FOUNDRY_PROFILE=shanghai forge build --silent contracts/shanghai/variants/BoundlessMarket.sol contracts/shanghai/legacy/BoundlessMarketLegacy.sol

- name: Verify shanghai legacy/ bytecode matches deployed Taiko impl
run: BOUNDLESS_OUT_DIR=out-shanghai BOUNDLESS_LEGACY_SNAPSHOT_DIR=contracts/shanghai/legacy python3 contracts/scripts/verify-legacy-bytecode.py

- name: Verify shanghai market/legacy storage layout interop
run: BOUNDLESS_OUT_DIR=out-shanghai python3 contracts/scripts/verify-storage-layout.py

- name: Run the contract suite under the shanghai profile
run: FOUNDRY_PROFILE=shanghai forge test --isolate

upgradability:
runs-on: ubuntu-latest
needs: contracts-changed
Expand Down
4 changes: 2 additions & 2 deletions contracts/scripts/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import {BoundlessRouter} from "../src/router/BoundlessRouter.sol";
import {ControlID} from "../src/blake3-groth16/ControlID.sol";
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import {ConfigLoader, DeploymentConfig} from "./Config.s.sol";
import {BoundlessMarket} from "../src/BoundlessMarket.sol";
import {BoundlessMarket as BoundlessMarketLegacy} from "../src/legacy/BoundlessMarketLegacy.sol";
import {BoundlessMarket} from "boundless-market/BoundlessMarket.sol";
import {BoundlessMarket as BoundlessMarketLegacy} from "boundless-market-legacy/BoundlessMarketLegacy.sol";
import {HitPoints} from "../src/HitPoints.sol";
import {BoundlessScriptBase} from "./BoundlessScript.s.sol";

Expand Down
4 changes: 2 additions & 2 deletions contracts/scripts/Manage.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import {Script} from "forge-std/Script.sol";
import {console2} from "forge-std/console2.sol";
import {Strings} from "openzeppelin/contracts/utils/Strings.sol";
import {IRiscZeroVerifier} from "risc0/IRiscZeroVerifier.sol";
import {BoundlessMarket} from "../src/BoundlessMarket.sol";
import {BoundlessMarket as BoundlessMarketLegacy} from "../src/legacy/BoundlessMarketLegacy.sol";
import {BoundlessMarket} from "boundless-market/BoundlessMarket.sol";
import {BoundlessMarket as BoundlessMarketLegacy} from "boundless-market-legacy/BoundlessMarketLegacy.sol";
import {BoundlessRouter} from "../src/router/BoundlessRouter.sol";
import {BoundlessMarketLib} from "../src/libraries/BoundlessMarketLib.sol";
import {ConfigLoader, DeploymentConfig} from "./Config.s.sol";
Expand Down
13 changes: 10 additions & 3 deletions contracts/scripts/verify-legacy-bytecode.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,21 @@
"""

import json
import os
import re
import sys
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parents[2]
ARTIFACT = REPO_ROOT / "out" / "BoundlessMarketLegacy.sol" / "BoundlessMarket.json"
DEPLOYED_HEX = REPO_ROOT / "contracts" / "test" / "legacy" / "deployed-bytecode.hex"
META_TOML = REPO_ROOT / "contracts" / "test" / "legacy" / "deployed-bytecode.meta.toml"
# Defaults check the Cancun/Base legacy. Override via env to check the Taiko legacy compiled under
# FOUNDRY_PROFILE=shanghai:
# BOUNDLESS_OUT_DIR=out-shanghai
# BOUNDLESS_LEGACY_SNAPSHOT_DIR=contracts/shanghai/legacy
_OUT_DIR = REPO_ROOT / os.environ.get("BOUNDLESS_OUT_DIR", "out")
_SNAPSHOT_DIR = REPO_ROOT / os.environ.get("BOUNDLESS_LEGACY_SNAPSHOT_DIR", "contracts/test/legacy")
ARTIFACT = _OUT_DIR / "BoundlessMarketLegacy.sol" / "BoundlessMarket.json"
DEPLOYED_HEX = _SNAPSHOT_DIR / "deployed-bytecode.hex"
META_TOML = _SNAPSHOT_DIR / "deployed-bytecode.meta.toml"


def strip0x(s: str) -> str:
Expand Down
8 changes: 6 additions & 2 deletions contracts/scripts/verify-storage-layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@
"""

import json
import os
import re
import sys
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parents[2]
NEW_ARTIFACT = REPO_ROOT / "out" / "BoundlessMarket.sol" / "BoundlessMarket.json"
LEGACY_ARTIFACT = REPO_ROOT / "out" / "BoundlessMarketLegacy.sol" / "BoundlessMarket.json"
# Default profile writes to ./out; the shanghai profile writes to ./out-shanghai. Point the script
# at the latter with `BOUNDLESS_OUT_DIR=out-shanghai` to verify the Taiko market/legacy pair.
_OUT_DIR = REPO_ROOT / os.environ.get("BOUNDLESS_OUT_DIR", "out")
NEW_ARTIFACT = _OUT_DIR / "BoundlessMarket.sol" / "BoundlessMarket.json"
LEGACY_ARTIFACT = _OUT_DIR / "BoundlessMarketLegacy.sol" / "BoundlessMarket.json"

# Top-level storage variables shared between the two contracts. Order +
# expected slot are part of the contract — any change here is a real
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import {
} from "risc0/IRiscZeroVerifier.sol";
import {IRiscZeroSetVerifier} from "risc0/IRiscZeroSetVerifier.sol";

import {IBoundlessMarket} from "./IBoundlessMarket.sol";
import {IBoundlessMarketCallback} from "./IBoundlessMarketCallback.sol";
import {IBoundlessMarket} from "./IBoundlessMarketLegacy.sol";
import {IBoundlessMarketCallback} from "./IBoundlessMarketCallbackLegacy.sol";
import {Account} from "./types/Account.sol";
import {AssessorJournal} from "./types/AssessorJournal.sol";
import {AssessorCallback} from "./types/AssessorCallback.sol";
Expand Down
54 changes: 54 additions & 0 deletions contracts/shanghai/legacy/LEGACY-FROZEN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# `contracts/shanghai/legacy/` — frozen audited tree (Taiko)

This subtree is a frozen copy of the pre-router `BoundlessMarket` and its transitive dependencies
**as deployed on Taiko mainnet**, compiled under the Shanghai EVM (`FOUNDRY_PROFILE=shanghai`). It
exists so the new router-based shanghai market can forward its pre-router legacy ABI to the audited
bytecode at the existing implementation address via a `fallback() + delegatecall` shim, without
re-introducing the legacy bodies into the new market's bytecode.

It is the Taiko/Shanghai counterpart of `contracts/src/legacy/` (which freezes the Base/Cancun
deployment). The two are separate because they reproduce different deployed bytecode: Taiko's impl
was compiled for the Shanghai EVM (no `tstore`/`mcopy`), so it uses the `sstore`/`sload`
`FulfillmentContext` and the `compat/Bytes` shim rather than the Cancun originals.

## Provenance

The sources here mirror the pre-router shanghai market suite (`contracts/shanghai/src/`) as it was
at the Taiko deployment. The only diffs from those sources are file-basename + import renames
(`BoundlessMarket.sol` → `BoundlessMarketLegacy.sol`, `IBoundlessMarket*.sol` →
`IBoundlessMarket*Legacy.sol`) so Forge writes artifacts to distinct `out-shanghai/` directories; the
contract **symbols** stay `BoundlessMarket` / `IBoundlessMarket*` so the build (with
`bytecode_hash = none`) is byte-identical to the deployed audited code.

The on-chain identity that ultimately matters is the deployed bytecode at the Taiko mainnet
`BoundlessMarket` proxy's pre-upgrade implementation address:

- proxy: `0xb3f5c7b4379052eade8c7f3fa6da37fb871da28b`
- impl: `0x6c2d2c33e9a7cd0e1b39dc218f472e4bf534523b`

The bytecode-parity invariant under `deployed-bytecode.hex` + `deployed-bytecode.meta.toml` (in this
directory) is the load-bearing check.

## Verification

```bash
# Bytecode parity: this tree compiles to the deployed Taiko impl (modulo immutables).
FOUNDRY_PROFILE=shanghai forge build contracts/shanghai/legacy/BoundlessMarketLegacy.sol
BOUNDLESS_OUT_DIR=out-shanghai BOUNDLESS_LEGACY_SNAPSHOT_DIR=contracts/shanghai/legacy \
uv run contracts/scripts/verify-legacy-bytecode.py

# Storage-layout interop: the new shanghai market can safely delegatecall this legacy impl.
FOUNDRY_PROFILE=shanghai forge build \
contracts/shanghai/variants/BoundlessMarket.sol contracts/shanghai/legacy/BoundlessMarketLegacy.sol
BOUNDLESS_OUT_DIR=out-shanghai uv run contracts/scripts/verify-storage-layout.py
```

(Each command is a single line; the `\` continuations above are for documentation only — paste them
as one line.)

## Freeze policy

Do not modify any file in this tree. Any drift between the frozen source and the deployed audited
bytecode is a real issue — fix the drift, do not edit the verification script or this snapshot to
mask it. The deployed implementation is reused directly as the new market's `LEGACY_IMPL`; this tree
is the source-of-record + the interop safety check, not a redeployment target.
74 changes: 74 additions & 0 deletions contracts/shanghai/legacy/compat/Bytes.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// SPDX-License-Identifier: MIT
// Shanghai-compatible replacement for OpenZeppelin's Bytes.sol (v5.4.0)
// Replaces mcopy with a manual memory copy loop for pre-Cancun EVM compatibility.
pragma solidity ^0.8.24;

import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";

library Bytes {
function indexOf(bytes memory buffer, bytes1 s) internal pure returns (uint256) {
return indexOf(buffer, s, 0);
}

function indexOf(bytes memory buffer, bytes1 s, uint256 pos) internal pure returns (uint256) {
uint256 length = buffer.length;
for (uint256 i = pos; i < length; ++i) {
if (bytes1(_unsafeReadBytesOffset(buffer, i)) == s) {
return i;
}
}
return type(uint256).max;
}

function lastIndexOf(bytes memory buffer, bytes1 s) internal pure returns (uint256) {
return lastIndexOf(buffer, s, type(uint256).max);
}

function lastIndexOf(bytes memory buffer, bytes1 s, uint256 pos) internal pure returns (uint256) {
unchecked {
uint256 length = buffer.length;
for (uint256 i = Math.min(Math.saturatingAdd(pos, 1), length); i > 0; --i) {
if (bytes1(_unsafeReadBytesOffset(buffer, i - 1)) == s) {
return i - 1;
}
}
return type(uint256).max;
}
}

function slice(bytes memory buffer, uint256 start) internal pure returns (bytes memory) {
return slice(buffer, start, buffer.length);
}

function slice(bytes memory buffer, uint256 start, uint256 end) internal pure returns (bytes memory) {
uint256 length = buffer.length;
end = Math.min(end, length);
start = Math.min(start, end);

uint256 len = end - start;
bytes memory result = new bytes(len);
// Manual word-by-word copy (Shanghai-compatible, no mcopy)
assembly ("memory-safe") {
let src := add(add(buffer, 0x20), start)
let dst := add(result, 0x20)
let remaining := len
for {} iszero(lt(remaining, 0x20)) {} {
mstore(dst, mload(src))
src := add(src, 0x20)
dst := add(dst, 0x20)
remaining := sub(remaining, 0x20)
}
if remaining {
let mask := sub(shl(shl(3, remaining), 1), 1)
mstore(dst, or(and(mload(dst), mask), and(mload(src), not(mask))))
}
}
return result;
}

function _unsafeReadBytesOffset(bytes memory buffer, uint256 offset) private pure returns (bytes32 value) {
assembly ("memory-safe") {
value := mload(add(add(buffer, 0x20), offset))
}
}
}
1 change: 1 addition & 0 deletions contracts/shanghai/legacy/deployed-bytecode.hex

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions contracts/shanghai/legacy/deployed-bytecode.meta.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Reference snapshot of the BoundlessMarket implementation deployed at the Taiko
# mainnet proxy (the pre-router market, compiled under FOUNDRY_PROFILE=shanghai).
# Used by scripts/verify-legacy-bytecode.py to assert that contracts/shanghai/legacy/
# compiles to the same bytecode (modulo immutable slots baked in at deploy time).
#
# Refresh procedure:
# cast code 0x6c2d2c33e9a7cd0e1b39dc218f472e4bf534523b \
# --rpc-url https://rpc.mainnet.taiko.xyz \
# > contracts/shanghai/legacy/deployed-bytecode.hex
# and update `fetched_at_block` below.

network = "taiko-mainnet"
chain_id = 167000
proxy = "0xb3f5c7b4379052eade8c7f3fa6da37fb871da28b"
impl = "0x6c2d2c33e9a7cd0e1b39dc218f472e4bf534523b"
fetched_at_block = 7982471

# Constructor immutables baked into the deployed bytecode. The compiled
# shanghai/legacy/ artifact has zeros at these positions; the verification
# script masks them out for the body-match check and then re-extracts each
# baked-in value and asserts it matches the expected value below.

[immutables]
VERIFIER = "0x607d196b43abc5d9BE3c7Fb8e336Ca82fec18C45"
ASSESSOR_ID = "0x6c5a03c0785e91bc0ad0db486004116010680a03af4e712bcca3188e56694100"
COLLATERAL_TOKEN_CONTRACT = "0xC284A781072442cc1882a8Db4573990B7B49DaC4"
DEPRECATED_ASSESSOR_ID = "0x0000000000000000000000000000000000000000000000000000000000000000"
DEPRECATED_ASSESSOR_EXPIRES_AT = 1773868771
APPLICATION_VERIFIER = "0x607d196b43abc5d9BE3c7Fb8e336Ca82fec18C45"
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// as found in the LICENSE-BSL file.
pragma solidity ^0.8.26;

import {IBoundlessMarket} from "../IBoundlessMarket.sol";
import {IBoundlessMarket} from "../IBoundlessMarketLegacy.sol";

library MerkleProofish {
// Compute the root of the Merkle tree given all of its leaves.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pragma solidity ^0.8.26;

import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {IBoundlessMarket} from "../IBoundlessMarket.sol";
import {IBoundlessMarket} from "../IBoundlessMarketLegacy.sol";

using OfferLibrary for Offer global;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// as found in the LICENSE-BSL file.
pragma solidity ^0.8.26;

import {IBoundlessMarket} from "../IBoundlessMarket.sol";
import {IBoundlessMarket} from "../IBoundlessMarketLegacy.sol";

type RequestId is uint256;

Expand Down
Loading
Loading