Skip to content

AggLayer: Faucet registry storage in AggLayerBridge #2172

@mmagician

Description

@mmagician

Summary

Several issues (#1893, #2140) touch on how the AggLayer bridging flow deals with the faucet registry. Let's use this issue as a consolidated place to align on how the faucet registry should be stored and what responsibilities it has.

The main question is: what data lives in the bridge’s registry vs. in the faucet’s own storage, an, as a result, who is responsible for amount and address conversion?

Background

  • The AggLayer bridge maintains a registry of AggLayer faucets and rejects bridge operations for unregistered ones.
  • I think we have consensus on storing a map faucet_registry in the AggLayerBridge. The mapping would look like:
    • faucet_registry: FAUCET_ACCOUNT_ID -> VALUE
  • Conversion between Miden asset amounts and native (L1) token amounts requires:
    • identifying the native token (e.g. ERC20 address), and
    • applying a token-specific scaling factor.

Proposed storage in AggLayerBridge:

faucet_registry map

The registry is the authoritative allowlist. Whether it is also the authoritative source of conversion parameters is the core decision to be made.

  • Key: FAUCET_ACCOUNT_ID
  • Value: either:
    • an EMPTY_WORD (i.e. membership-only registry), or
    • a packed word containing conversion metadata.

If the value is non-empty, the suggested layout is:

  • native_token_address (20 bytes, could be packed into 3 Felts)
  • scale (u8)

Option A - Store conversion data in the bridge registry

  • faucet_registry stores:
    • native token address
    • scale
  • Conversion logic lives in AggLayerBridge.
  • Faucets do not need to store conversion metadata themselves.

Pros

  • Bridge can compute [NATIVE_AMOUNT, NATIVE_IDENTIFIER] locally
  • No FPI call needed
  • Single conversion implementation used by bridge logic
  • Faucet storage stays minimal
    Cons
  • The address format we use in Merkle hashing is stored as 5x u32 (=20 bytes). We could store a packed version, but that requires extra format conversion logic.
  • High coupling between the bridge and faucets
  • Less extensible & customizable

Option B - Store conversion data in the faucet

  • faucet_registry is membership-only (EMPTY_WORD).
  • Each faucet stores:
    • native token address
    • scale
  • Bridge obtains the final conversion results via an FPI call to the faucet.

Option B.2 - Obtain conversion info via FPI, convert locally

  • Bridge obtains only the "conversion info" (i.e. scale) but does the conversion locally. This is a bit of a hybrid with an unclear split of responsibilities so I think it's the least optimal choice, but flagging it here for completeness.

Pros

  • Conversion logic and parameters live with the asset-specific contract (if we ever have assets with non-uniform conversion)
  • Bridge stays simpler
  • Faucets are more flexible
    Cons
  • Requires FPI calls during bridging
  • Conversion logic likely duplicated in each faucet

Conclusion

My personal preference is for Option B, with the main benefit being the de-coupling of the bridge and faucet logic.

Metadata

Metadata

Assignees

Labels

agglayerPRs or issues related to AggLayer bridging integration

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions