Skip to content

feat(agglayer): configure priced fee policies at deployment - #3486

Open
partylikeits1983 wants to merge 22 commits into
nextfrom
ajl-agglayer-constant-fee-policy
Open

feat(agglayer): configure priced fee policies at deployment#3486
partylikeits1983 wants to merge 22 commits into
nextfrom
ajl-agglayer-constant-fee-policy

Conversation

@partylikeits1983

@partylikeits1983 partylikeits1983 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Closes #3487
Related to #3367

Adds AggLayerBridge::account_builder and AggLayerFaucet::account_builder, which take the fee policy manager as a required argument so an account cannot be deployed unpriced.

NetworkNotePricer provides one-call constructors for production BasicConstantFeePolicy managers, pricing every consumed note root from benchmarked costs.

Fee-enabled E2E cases cover CLAIM through recipient balance and B2AGG through BURN.

partylikeits1983 and others added 18 commits August 4, 2026 16:39
Make the fee policy manager a required argument of the AggLayer account
builders instead of an optional setter whose absence panicked in
`build()`, and expose the faucet's asset callback flag on the builder.

The bridge-in claim-to-P2ID test regained the callback-enabled faucet it
lost when it moved to the priced helper, and the bridge-out test keeps
pinning all 32 bundled Solidity MTF vectors.
Both AggLayer network accounts install the ConstantFeeManager and
allowlist CONSTANT_FEE_POLICY_CONFIG notes, so their ADMIN role can
reprice a schedule that was otherwise frozen at deployment. The bridge
sizes the sponsorship of every MINT and BURN note it creates from the
faucet's schedule, so leaving the faucet frozen would stall bridging
once the chain's verification base fee moved.

The faucet moves from Authority::OwnerControlled to RbacControlled to
make that reachable at all: with the bridge as its Ownable2Step owner,
every authority-gated procedure was gated on a sender nothing can
produce. Minting and burning are unaffected, since MintOwnerOnly and
BurnOwnerOnly check the owner slot directly rather than going through
Authority.

The config note is scheduled free rather than at its benchmarked cost.
Consuming one is the only route to set_note_fee, so pricing it would let
the schedule put the note that repairs it out of reach.
Documents what the fee policy work changed: the deployed schedules and
how they are repriced, the faucet's move to RBAC and the resulting split
between owner-gated minting and ADMIN-gated configuration, and the
CONSTANT_FEE_POLICY_CONFIG note.

Also records the operational consequence of a priced schedule that was
previously undocumented: a note with a non-zero schedule entry can only
be consumed alongside FEE_SPONSORSHIP notes covering it, regardless of
the chain's own base fee, so every management note needs a sponsorship
funded with it.

Pins the faucet allowlist the way the bridge's already was, and covers
repricing a paused bridge.
…-fee-policy

# Conflicts:
#	crates/miden-testing/tests/agglayer/test_utils.rs
Adds a find_output_note helper for the six copies of the
output-note-by-script-root predicate, returns Option<Note> from
add_fee_sponsorship so the fee axis stops being threaded through
if/else blocks, and uses the existing authenticated_input_notes
iterator overload to restore the builder chains.

The priced-account pin test now reuses build_managed_account instead
of rebuilding the same two fixtures verbatim.
@partylikeits1983
partylikeits1983 marked this pull request as ready for review August 6, 2026 13:58

@Fumuran Fumuran left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! It's a partial review, I only looked through non-testing code. Left just two not-that-important questions.

Comment thread crates/miden-agglayer/src/bridge.rs Outdated
Comment thread crates/miden-agglayer/src/lib.rs Outdated

@zeapoz zeapoz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Didn't go through the new tests in minute detail but they seem alright from a quick glance

Comment thread crates/miden-agglayer/src/lib.rs Outdated
Comment thread CHANGELOG.md Outdated
partylikeits1983 and others added 4 commits August 7, 2026 14:46
Co-authored-by: zeapoz <zeapo@pm.me>
…lpers

Address review feedback on the deployment builder API:
- drop the AggLayerBridgeAccountBuilder and AggLayerFaucetAccountBuilder
  wrappers; AggLayerBridge::account_builder and AggLayerFaucet::account_builder
  now return the underlying AccountBuilder directly
- move the test-only helpers (zero_fee_policy_manager, faucet_account_builder,
  create_existing_agglayer_faucet) into miden_agglayer::testing
Address review feedback on the note-set naming: the former fee_policy_notes
returned the full set of notes the account actually accepts, so it becomes
allowed_notes, and the component-specific subsets become bridge_notes and
faucet_notes. Record the rename in the changelog and move this PR's entries
back under the unreleased v0.17.0 section, where the released v0.16.0 section
had absorbed them during the merge from next.
@partylikeits1983 partylikeits1983 added agglayer PRs or issues related to AggLayer bridging integration pr-from-maintainers PRs that come from internal contributors or integration partners. They should be given priority labels Aug 7, 2026
@partylikeits1983 partylikeits1983 self-assigned this Aug 7, 2026
Comment on lines +513 to +518
pub fn allowed_notes() -> BTreeSet<NoteScriptRoot> {
let mut notes = Self::bridge_notes();
notes.extend(AuthNetworkAccount::default_allowed_note_scripts());
notes
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why exactly do we need to differentiate between bridge_notes and allowed_notes? Couldn't we just extend the set of allowed notes with AuthNetworkAccount::default_allowed_note_scripts()?

Comment on lines +290 to +293
The config note's own script root is deliberately scheduled at zero on both accounts, even though
it has a benchmarked cost like any other note. Consuming one is the only route to `set_note_fee`,
so a priced entry could raise the config note's own fee past what a sponsor covers and put the
schedule permanently out of reach.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order for the network account to be able to consume the config note, the bridge still has to pay a fee somehow.

And if we price the config note at zero, then the owner that sends a config note to the bridge has no way of estimating how much they should sponsor.

So I think we need to also price-in the config notes

| **Integration Service** (offchain) | Observes L1 events (deposits, GER updates) and creates UPDATE_GER and CLAIM notes on Miden. Trusted to provide correct proofs and data. | Not an onchain entity; creates notes targeting bridge/faucet |
| **Bridge Operator** (offchain) | Deploys bridge and faucet accounts. Creates CONFIG_AGG_BRIDGE notes to register faucets. Must hold the `FAUCET_MNGR` role. | Not an onchain entity; creates config notes |
| **Role Admin** (offchain) | Holds the bridge's `ADMIN` role and manages role membership via RBAC_CONFIG notes. Root authority: effective admin of every operational role unless delegated, so compromise of this key is equivalent to compromise of all operational roles (see [Section 2.5](#25-administration)). | Not an onchain entity; creates RBAC_CONFIG notes |
| **Role Admin** (offchain) | Holds the `ADMIN` role on the bridge and on each faucet. Manages bridge role membership via RBAC_CONFIG notes and reprices both accounts' fee schedules via CONSTANT_FEE_POLICY_CONFIG notes. Root authority: effective admin of every operational role unless delegated, and on a faucet it can additionally retarget the `Ownable2Step` owner, so compromise of this key is equivalent to compromise of all operational roles (see [Section 2.5](#25-administration)). | Not an onchain entity; creates RBAC_CONFIG and CONSTANT_FEE_POLICY_CONFIG notes |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does this fit in with #2724?

The idea was that the faucet does not have ownership transfer.

Comment on lines +109 to +140
crate::create_agglayer_faucet_builder(
seed,
token_symbol,
decimals,
max_supply,
initial_supply,
admin,
bridge_account_id,
fee_policy_manager,
)
}

/// Creates an existing agglayer faucet account with the specified configuration, priced by a
/// zero-fee policy and administered by [`bridge_admin_account_id`].
pub fn create_existing_agglayer_faucet(
seed: Word,
token_symbol: &str,
decimals: u8,
max_supply: Felt,
initial_supply: Felt,
bridge_account_id: AccountId,
) -> Account {
faucet_account_builder(
seed,
token_symbol,
decimals,
max_supply,
initial_supply,
bridge_admin_account_id(),
bridge_account_id,
zero_fee_policy_manager(AggLayerFaucet::allowed_notes()),
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could get rid of faucet_account_builder and have the callers directly call create_agglayer_faucet_builder

Comment on lines +199 to +208
create_agglayer_faucet_builder(
seed,
token_symbol,
decimals,
max_supply,
Felt::ZERO,
admin,
bridge_account_id,
fee_policy_manager,
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we inline create_agglayer_faucet_builder?

Combined with the other comments, this would effectively collapse all callers to use AggLayerFaucet::account_builder

@mmagician mmagician left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more comment: after this PR, what is missing to then close #3367?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agglayer PRs or issues related to AggLayer bridging integration pr-from-maintainers PRs that come from internal contributors or integration partners. They should be given priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Configure constant note fees for AggLayer bridge and faucet accounts

4 participants