Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
3167760
chore: unify b2agg note storage layout with claim note
mmagician Feb 10, 2026
62d903b
chore: clarify destinationAddress in CLAIM note
mmagician Feb 10, 2026
ea5c09b
feat: mem_store_double_word_unaligned
mmagician Feb 10, 2026
2c7d070
feat: compute leaf value for bridging out
mmagician Feb 10, 2026
b82f071
chore: update comment about origin network ID
mmagician Feb 11, 2026
545ba44
fix: write_address_to_memory had incorrect address arithmetic
cursoragent Feb 11, 2026
5286915
fix: handling of dest address and ID in B2AGG
mmagician Feb 11, 2026
4f58246
feat: reverse_limbs_and_change_byte_endianness
mmagician Feb 11, 2026
78b8ba9
chore: integrate byte and limb swapping to bridging
mmagician Feb 11, 2026
5a91cac
fix: swap origin net ID endianness; rearrange mem writes
mmagician Feb 11, 2026
c011f8d
chore: pad mem with zeros after metadata
mmagician Feb 12, 2026
589c7a9
feat: store LET frontier in double-word array
mmagician Feb 11, 2026
4e96929
feat: frontier test generation from param"d leaves
mmagician Feb 11, 2026
e35c439
feat: verify computed LER against expected root
mmagician Feb 11, 2026
b9b0aed
write leaf"s amounts to JSON
mmagician Feb 11, 2026
fbc27c3
fix: compare LET by elements, rev elements per word
mmagician Feb 11, 2026
6f2af24
feat: add faucet registry
mmagician Feb 16, 2026
d7b3017
chore: CONFIG note docs
mmagician Feb 12, 2026
c767e60
chore: simplify creation of existing agg faucet w/supply
mmagician Feb 12, 2026
ed8b51d
lint
mmagician Feb 16, 2026
4dbf355
chore: TODO on bridge admin validation
mmagician Feb 16, 2026
bbf63b1
chore: simplify stack operations
Copilot Feb 16, 2026
d94c035
chore: Replace `unwrap()` with `expect()` for StorageSlotName parsing…
Copilot Feb 16, 2026
a1c1499
Update crates/miden-testing/tests/agglayer/bridge_out.rs
mmagician Feb 16, 2026
140ca14
Merge branch 'agglayer-new' into mmagician-bridge-out-store-frontier
mmagician Feb 16, 2026
636bd41
chore: only truncate at the end
mmagician Feb 16, 2026
e37cb44
Merge branch 'mmagician-bridge-out-store-frontier' into mmagician-cur…
mmagician Feb 16, 2026
29776a7
chore: move (de)ser logic to test_utils
mmagician Feb 16, 2026
fc7d332
chore: organize test_utils better
mmagician Feb 16, 2026
c06b6d5
chore: serialize amounts as strings in mmr test vecs
mmagician Feb 16, 2026
4d71785
test bridge_out frontier persistence across two consumes
cursoragent Feb 17, 2026
857d718
fix bridge_out frontier reload num_leaves endianness
cursoragent Feb 17, 2026
ed8a052
test bridge_out with shared multi-note helper and 32-leaf case
cursoragent Feb 17, 2026
bf8991d
refactor bridge_out coverage to direct 32-leaf burn flow
cursoragent Feb 17, 2026
afc240c
refactor MMR vectors to seeded per-leaf destinations
cursoragent Feb 17, 2026
3bfb9d3
chore: cleanup tests
mmagician Feb 17, 2026
1845253
Merge branch 'agglayer-new' into mmagician-bridge-out-store-frontier
mmagician Feb 18, 2026
37ba1f1
Merge branch 'mmagician-bridge-out-store-frontier' into mmagician-cur…
mmagician Feb 18, 2026
4f9d96b
Merge branch 'agglayer-new' into mmagician-cursor-bridge-out-componen…
mmagician Feb 18, 2026
ed63be4
Merge branch 'mmagician-cursor-bridge-out-component-implementation-de…
cursoragent Feb 18, 2026
d22a67f
fix: rustfmt line wrapping + clippy needless_range_loop
cursoragent Feb 18, 2026
00bc41d
fix: read addr conversion slot in reverse
mmagician Feb 18, 2026
43e0bb0
chore: use non-zero address
mmagician Feb 18, 2026
493f126
Merge branch 'agglayer-new' into mmagician-cursor-agglayer-faucet-reg…
mmagician Feb 18, 2026
f271bd1
chore: rename loc const to distinguish
mmagician Feb 18, 2026
6220ee2
chore: use loc const in create_burn_note
mmagician Feb 18, 2026
2701f03
chore: bring back doc and inline comments
mmagician Feb 18, 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Features

- Added AggLayer faucet registry to bridge account with conversion metadata, `CONFIG_AGG_BRIDGE` note for faucet registration, and FPI-based asset conversion in `bridge_out` ([#2426](https://github.com/0xMiden/miden-base/pull/2426)).
- Enable `CodeBuilder` to add advice map entries to compiled scripts ([#2275](https://github.com/0xMiden/miden-base/pull/2275)).
- Added `BlockNumber::MAX` constant to represent the maximum block number ([#2324](https://github.com/0xMiden/miden-base/pull/2324)).
- Added single-word `Array` standard ([#2203](https://github.com/0xMiden/miden-base/pull/2203)).
Expand Down
122 changes: 122 additions & 0 deletions crates/miden-agglayer/asm/bridge/agglayer_faucet.masm
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use miden::agglayer::bridge_in
use miden::core::sys
use miden::agglayer::utils
use miden::agglayer::asset_conversion
use miden::agglayer::eth_address
use miden::protocol::active_account
Expand All @@ -16,6 +18,12 @@ use miden::core::word
# The slot in this component's storage layout where the bridge account ID is stored.
const BRIDGE_ID_SLOT = word("miden::agglayer::faucet")

# Storage slots for conversion metadata.
# Slot 1: [addr_felt0, addr_felt1, addr_felt2, addr_felt3] — first 4 felts of origin token address
const CONVERSION_INFO_1_SLOT = word("miden::agglayer::faucet::conversion_info_1")
# Slot 2: [addr_felt4, origin_network, scale, 0] — remaining address felt + origin network + scale
const CONVERSION_INFO_2_SLOT = word("miden::agglayer::faucet::conversion_info_2")

const PROOF_DATA_WORD_LEN = 134
const LEAF_DATA_WORD_LEN = 8
const OUTPUT_NOTE_DATA_WORD_LEN = 2
Expand Down Expand Up @@ -70,6 +78,120 @@ const P2ID_OUTPUT_NOTE_AMOUNT_MEM_PTR = 611

const ERR_INVALID_CLAIM_PROOF = "invalid claim proof"

# CONVERSION METADATA HELPERS
# =================================================================================================

#! Returns the origin token address (5 felts) from faucet conversion storage.
#!
#! Reads conversion_info_1 (first 4 felts of address) and conversion_info_2 (5th felt)
#! from storage.
#!
#! Inputs: []
#! Outputs: [addr0, addr1, addr2, addr3, addr4]
#!
#! Invocation: exec
pub proc get_origin_token_address
push.CONVERSION_INFO_1_SLOT[0..2]
exec.active_account::get_item
# => [addr3, addr2, addr1, addr0]
exec.word::reverse
# => [addr0, addr1, addr2, addr3]

# Read slot 2: [0, scale, origin_network, addr4]
push.CONVERSION_INFO_2_SLOT[0..2]
exec.active_account::get_item
# => [0, scale, origin_network, addr4, addr0, addr1, addr2, addr3]

# Keep only addr4 from slot 2 and append it after slot 1 limbs
drop drop drop
movdn.4
# => [addr0, addr1, addr2, addr3, addr4]
end

#! Returns the origin network identifier from faucet conversion storage.
#!
#! Inputs: []
#! Outputs: [origin_network]
#!
#! Invocation: exec
pub proc get_origin_network
push.CONVERSION_INFO_2_SLOT[0..2]
exec.active_account::get_item
# => [0, scale, origin_network, addr4]

drop drop swap drop
# => [origin_network]
end

#! Returns the scale factor from faucet conversion storage.
#!
#! Inputs: []
#! Outputs: [scale]
#!
#! Invocation: exec
pub proc get_scale
push.CONVERSION_INFO_2_SLOT[0..2]
exec.active_account::get_item
# => [0, scale, origin_network, addr4]

drop movdn.2 drop drop
# => [scale]
end

#! Converts a native Miden asset amount to origin asset data using the stored
#! conversion metadata (origin_token_address, origin_network, and scale).
#!
#! This procedure is intended to be called via FPI from the bridge account.
#! It reads the faucet's conversion metadata from storage, scales the native amount
#! to U256 format, and returns the result along with origin token address and network.
#!
#! Inputs: [amount, pad(15)]
#! Outputs: [AMOUNT_U256[0], AMOUNT_U256[1], addr0, addr1, addr2, addr3, addr4, origin_network, pad(2)]
#!
#! Where:
#! - amount: The native Miden asset amount
#! - AMOUNT_U256: The scaled amount as 8 u32 limbs (little-endian U256)
#! - addr0..addr4: Origin token address (5 felts, u32 limbs)
#! - origin_network: Origin network identifier
#!
#! Invocation: call
pub proc asset_to_origin_asset
# => [amount, pad(15)]

# Step 1: Get scale from storage
exec.get_scale
# => [scale, amount, pad(15)]
swap
# => [amount, scale, pad(15)]

# Step 2: Scale amount to U256
exec.asset_conversion::scale_native_amount_to_u256
exec.asset_conversion::reverse_limbs_and_change_byte_endianness
# => [U256_LO(4), U256_HI(4), pad(15)]

# Step 3: Get origin token address
exec.get_origin_token_address
# => [addr0, addr1, addr2, addr3, addr4, U256_LO(4), U256_HI(4), pad(15)]

# Move address below the U256 amount
repeat.5 movdn.12 end
# => [U256_LO(4), U256_HI(4), addr0, addr1, addr2, addr3, addr4, pad(15)]

# Step 4: Get origin network
exec.get_origin_network
exec.utils::swap_u32_bytes
# => [origin_network, U256_LO(4), U256_HI(4), addr0..addr4, pad(15)]

# Move origin_network after the address fields
movdn.13
# => [U256_LO(4), U256_HI(4), addr0, addr1, addr2, addr3, addr4, origin_network, pad(15)]

exec.sys::truncate_stack
end

# CLAIM PROCEDURES
# =================================================================================================

#! Inputs: [LEAF_DATA_KEY, PROOF_DATA_KEY]
#! Outputs: []
#!
Expand Down
45 changes: 45 additions & 0 deletions crates/miden-agglayer/asm/bridge/bridge_config.masm
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use miden::protocol::native_account

# CONSTANTS
# =================================================================================================

const FAUCET_REGISTRY_SLOT=word("miden::agglayer::bridge::faucet_registry")
const IS_REGISTERED_FLAG=1

# PUBLIC INTERFACE
# =================================================================================================

#! Registers a faucet in the bridge's faucet registry.
#!
#! Writes `KEY -> [1, 0, 0, 0]` into the `faucet_registry` map, where
#! `KEY = [faucet_id_prefix, faucet_id_suffix, 0, 0]`.
#!
#! The sentinel value `[1, 0, 0, 0]` distinguishes registered faucets from
#! non-existent entries (SMTs return EMPTY_WORD for missing keys).
#!
#! TODO: Currently, no sender validation is performed — anyone can register a faucet.
#! Tracked in https://github.com/0xMiden/miden-base/issues/2450
#!
#! Inputs: [faucet_id_prefix, faucet_id_suffix, pad(14)]
#! Outputs: [pad(16)]
#!
#! Invocation: call
pub proc register_faucet
# => [faucet_id_prefix, faucet_id_suffix, pad(14)]

# set_map_item expects [slot_id(2), KEY(4), VALUE(4)] and returns [OLD_VALUE(4)].
push.IS_REGISTERED_FLAG
# => [IS_REGISTERED_FLAG, slot_id_prefix, slot_id_suffix, pad(14)]

movdn.7
# => [[slot_id_prefix, slot_id_suffix, 0, 0], [0, 0, 0, IS_REGISTERED_FLAG], pad(9)]

# Place slot ID on top
push.FAUCET_REGISTRY_SLOT[0..2]
# Stack: [slot0, slot1, [prefix, suffix, 0, 0], [0, 0, 0, 1], pad(9)]

exec.native_account::set_map_item
# => [OLD_VALUE(4), pad(9)]

dropw
end
Loading