You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(agglayer): make bridge network ID a deployment setting (#3062)
* feat(agglayer): make bridge network ID a deployment setting
The bridge's AggLayer network ID was hardcoded as the MASM constant
MIDEN_NETWORK_ID and compiled directly into the bridge contract, baking
it into the bridge code commitment. This forced testnet/mainnet, which
may use different network IDs, to ship different bridge binaries.
Store the network ID in the bridge account instead:
- Add a `network_id` value storage slot (`agglayer::bridge::network_id`),
written once at account creation.
- `bridge_in`/`bridge_out` read it via a new `bridge_config::load_network_id`
helper instead of `push.MIDEN_NETWORK_ID`, so the bridge code commitment
is identical across all networks.
- Require `network_id` in `AggLayerBridge::new` and
`create_(existing_)bridge_account`; add an `AggLayerBridge::network_id`
reader and `network_id_slot_name` accessor.
- Remove the hardcoded `MIDEN_NETWORK_ID` constant entirely (MASM
`constants.masm` and its build.rs parsing). Tests keep a fixture-only
constant matching the bundled Solidity claim vectors.
The ID is never mutated by any bridge procedure, so it is effectively
immutable for the life of the account. Adds bridge-in and bridge-out tests
proving a bridge configured with a non-default network ID enforces it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Apply suggestions from code review
Co-authored-by: Marti <marcin.gorny.94@protonmail.com>
* fix: remove unused AggLayerBridge import in bridge_in test
The top-level import is shadowed by a function-local `use` in
test_bridge_in_claim_to_p2id, so clippy flags it as unused with
-D warnings.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude (Opus) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,9 @@
1
1
# Changelog
2
2
3
+
## v0.16.0 (TBD)
4
+
5
+
-[BREAKING] Changed AggLayerBridge to store its AggLayer network ID in account storage ([#3062](https://github.com/0xMiden/protocol/pull/3062)).
6
+
3
7
## v0.15.2 (2026-06-05)
4
8
5
9
-[BREAKING]`AuthNetworkAccount` now gates transaction scripts with a root allowlist instead of banning them outright, enabling network accounts to run approved tx scripts such as setting the expiration delta ([#3028](https://github.com/0xMiden/protocol/pull/3028)).
Copy file name to clipboardExpand all lines: crates/miden-agglayer/SPEC.md
+7-7Lines changed: 7 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -93,7 +93,7 @@ The `CLAIM` note is consumed by the bridge account:
93
93
`P2ID` note targeted at the recipient directly. The asset must have been previously
94
94
locked into the bridge by a prior bridge-out for the same token.
95
95
96
-
Inside `bridge_in::claim`, immediately after proof and leaf data are piped into memory, the bridge asserts the leaf's `destination_network` equals the global MASM constant `MIDEN_NETWORK_ID` in `asm/agglayer/common/constants.masm`(after `swap_u32_bytes` on the LE-packed memory limb). The same value is exposed to Rust as `AggLayerBridge::MIDEN_NETWORK_ID`, matching Solidity test vectors.
96
+
Inside `bridge_in::claim`, immediately after proof and leaf data are piped into memory, the bridge asserts the leaf's `destination_network` equals the bridge's configured network ID (after `swap_u32_bytes` on the LE-packed memory limb). The network ID is a deployment setting passed to `create_bridge_account` and stored in the `agglayer::bridge::network_id` slot; `bridge_config::load_network_id` reads it at runtime. It is set once at account creation and never mutated.
97
97
This mirrors Solidity `claimAsset` destination-network checks.
98
98
99
99
TODO: The leaf type field is not validated to be `LEAF_TYPE_ASSET` (0)
@@ -259,14 +259,14 @@ in the map the procedure panics with `ERR_GER_ALREADY_REGISTERED`.
259
259
|**Inputs**|`[PROOF_DATA_KEY, LEAF_DATA_KEY, faucet_mint_amount, pad(7)]` on the operand stack; proof data and leaf data in the advice map keyed by `PROOF_DATA_KEY` and `LEAF_DATA_KEY` respectively |
260
260
|**Outputs**|`[pad(16)]`|
261
261
|**Context**| Consuming a `CLAIM` note on the bridge account |
262
-
|**Panics**| Leaf `destination_network` does not match `agglayer::common::constants::MIDEN_NETWORK_ID`; invalid leaf type; GER not known; global index invalid; Merkle proof verification failed; (origin token address, origin network) pair not in token registry; claim already spent; amount conversion mismatch |
262
+
|**Panics**| Leaf `destination_network` does not match the bridge's configured network ID; invalid leaf type; GER not known; global index invalid; Merkle proof verification failed; (origin token address, origin network) pair not in token registry; claim already spent; amount conversion mismatch |
263
263
264
264
Validates a bridge-in claim and creates a MINT note targeting the faucet:
265
265
266
266
1. Pipes proof data and leaf data from the advice map into memory, verifying preimage
267
-
integrity, then asserts the leaf's `destination_network` matches the global
268
-
`MIDEN_NETWORK_ID` constant (`asm/agglayer/common/constants.masm`) after `swap_u32_bytes` on
269
-
the LE-packed limb (same convention as other AggLayer bridge-in u32 felts in memory).
267
+
integrity, then asserts the leaf's `destination_network` matches the bridge's configured
268
+
network ID (read from the `agglayer::bridge::network_id` storage slot) after `swap_u32_bytes`
269
+
on the LE-packed limb (same convention as other AggLayer bridge-in u32 felts in memory).
270
270
2. Extracts the destination account ID from the leaf data's destination address
271
271
(via `eth_address::to_account_id`).
272
272
3. Validates the Merkle proof via `verify_leaf_bridge`: computes the leaf
@@ -540,8 +540,8 @@ The storage is divided into three logical regions: proof data (felts 0-535), lea
540
540
advice map as two keyed entries (`PROOF_DATA_KEY`, `LEAF_DATA_KEY`).
541
541
4. The `miden_claim_amount` is read from memory.
542
542
5.`bridge_in::claim` is called with `[PROOF_DATA_KEY, LEAF_DATA_KEY, miden_claim_amount]`
543
-
on the stack. The bridge asserts the leaf's `destination_network` matches the global
544
-
`MIDEN_NETWORK_ID` MASM constant, validates the proof, checks the claim nullifier, looks up the faucet via the token
543
+
on the stack. The bridge asserts the leaf's `destination_network` matches the bridge's
544
+
configured network ID, validates the proof, checks the claim nullifier, looks up the faucet via the token
545
545
registry, verifies the amount conversion, then builds a MINT output note targeting the faucet.
0 commit comments