Skip to content
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
9611f93
feat(agglayer): configure priced fee policies at deployment
partylikeits1983 Aug 4, 2026
059ec00
docs: document AggLayer constant fee policies
partylikeits1983 Aug 4, 2026
bd884d8
refactor(agglayer): add fee policy account builders
partylikeits1983 Aug 4, 2026
cd44ca2
Merge remote-tracking branch 'origin/next' into ajl-agglayer-constant…
partylikeits1983 Aug 4, 2026
ba4b1b7
refactor(agglayer): streamline fee policy builders
partylikeits1983 Aug 4, 2026
6a67dd0
test(agglayer): clarify fee manager names
partylikeits1983 Aug 4, 2026
96561ba
refactor(agglayer): simplify testing helper imports
partylikeits1983 Aug 4, 2026
0f51cac
test(agglayer): cover bridge flows with fees enabled
partylikeits1983 Aug 4, 2026
9be17fe
refactor(tests): unify AggLayer fee policy setup
partylikeits1983 Aug 4, 2026
bb76288
Merge branch 'next' into ajl-agglayer-constant-fee-policy
partylikeits1983 Aug 5, 2026
0814b44
fix: address fee policy deployment review
partylikeits1983 Aug 5, 2026
1d729e2
feat(agglayer): make deployed fee schedules repricable
partylikeits1983 Aug 5, 2026
0fd1985
docs(agglayer): specify fee schedule administration
partylikeits1983 Aug 5, 2026
b787c15
Merge remote-tracking branch 'origin/next' into ajl-agglayer-constant…
partylikeits1983 Aug 6, 2026
490df44
docs(agglayer): reword the SPEC term flagged by the spellchecker
partylikeits1983 Aug 6, 2026
0e1b272
chore: condense the AggLayer fee policy changelog entries
partylikeits1983 Aug 6, 2026
f821485
refactor(tests): deduplicate AggLayer fee-enabled test plumbing
partylikeits1983 Aug 6, 2026
8b05fec
Merge branch 'next' into ajl-agglayer-constant-fee-policy
partylikeits1983 Aug 6, 2026
a7fb9ac
Update CHANGELOG.md
partylikeits1983 Aug 7, 2026
c235c26
Merge remote-tracking branch 'origin/next' into ajl-agglayer-constant…
partylikeits1983 Aug 7, 2026
ef12824
refactor(agglayer): return AccountBuilder from the account builder he…
partylikeits1983 Aug 7, 2026
a524eb8
refactor(agglayer): rename the note-set accessors
partylikeits1983 Aug 7, 2026
08e36cb
refactor(agglayer): collapse the note-set accessors into allowed_notes
partylikeits1983 Aug 10, 2026
96158ee
refactor(agglayer): inline the account builders and drop the one-shot…
partylikeits1983 Aug 10, 2026
169193a
docs(agglayer): explain the zero-priced fee config note and flag #2724
partylikeits1983 Aug 10, 2026
fda6af8
test(agglayer): prove a sponsored repricing note reimburses the bridge
partylikeits1983 Aug 10, 2026
23a921e
Merge remote-tracking branch 'origin/next' into ajl-agglayer-constant…
partylikeits1983 Aug 10, 2026
b39b973
docs(agglayer): correct the faucet ownership claim - transfer is owne…
partylikeits1983 Aug 10, 2026
500c90e
docs(agglayer): simplify the fee policy wording
partylikeits1983 Aug 10, 2026
cc83cca
docs(agglayer): note that a priced-in margin delays repricing
partylikeits1983 Aug 10, 2026
e8799df
docs(agglayer): quantify the default pricing margin
partylikeits1983 Aug 10, 2026
f76a8a6
docs(agglayer): document the bridge-faucet schedule coupling
partylikeits1983 Aug 10, 2026
d5ba53a
docs(agglayer): correct the schedule-coupling consequence
partylikeits1983 Aug 10, 2026
7692424
docs(agglayer): state the schedule-coupling invariant instead of one …
partylikeits1983 Aug 10, 2026
a594880
docs(agglayer): state the full schedule-coupling rule
partylikeits1983 Aug 10, 2026
0a51e15
Merge branch 'next' into ajl-agglayer-constant-fee-policy
partylikeits1983 Aug 11, 2026
5ae37cd
docs(agglayer): trim fee administration spec
partylikeits1983 Aug 11, 2026
aceb9fa
fix(fees): price config notes without losing recovery
partylikeits1983 Aug 11, 2026
0909ada
docs(fees): correct the repricing recovery story
partylikeits1983 Aug 11, 2026
e628420
fix(agglayer): drop the unused allow_all burn policy from the faucet
partylikeits1983 Aug 11, 2026
90bfb86
chore: condense the AggLayer changelog, state the faucet ADMIN rotati…
partylikeits1983 Aug 11, 2026
0a76e8a
chore(agglayer): tidy the fee test fixtures and docs
partylikeits1983 Aug 11, 2026
79024f4
test(agglayer): pin the output-note counts in the fee-enabled E2E cases
partylikeits1983 Aug 11, 2026
819ad62
docs(agglayer): note the inert FEE_SPONSORSHIP schedule entry
partylikeits1983 Aug 11, 2026
031d88b
docs(agglayer): tighten the fee administration and faucet ADMIN caveats
partylikeits1983 Aug 11, 2026
3dbd2f5
docs(fees): compress the config-note operational notes
partylikeits1983 Aug 11, 2026
e3d2fb8
docs(agglayer): rewrap the faucet allowlist doc paragraph
partylikeits1983 Aug 12, 2026
d594193
Update crates/miden-agglayer/src/lib.rs
partylikeits1983 Aug 12, 2026
43263e3
Update crates/miden-agglayer/src/lib.rs
partylikeits1983 Aug 12, 2026
34a1e56
fix(fees): drop the sponsorship note from constant fee schedules
partylikeits1983 Aug 12, 2026
453ae90
docs(agglayer): disambiguate ADMIN and trim SPEC change narration
partylikeits1983 Aug 12, 2026
61fa16a
docs(agglayer): restore the AuthNetworkAccount link definition
partylikeits1983 Aug 12, 2026
cef6c2f
chore: trim the AggLayer changelog entry
partylikeits1983 Aug 12, 2026
195eb8e
docs(agglayer): say the bridge accepts three other standard notes
partylikeits1983 Aug 12, 2026
1110583
docs(agglayer): plainer wording in the allowlist and builder docs
partylikeits1983 Aug 12, 2026
a800a10
docs(fees): simplify the config note's operational notes
partylikeits1983 Aug 12, 2026
5972503
docs(agglayer): drop the duplicate issue link from the trust model table
partylikeits1983 Aug 12, 2026
6affaed
docs(agglayer): name the components the faucet shares with the bridge
partylikeits1983 Aug 12, 2026
af1fb34
chore: move the AggLayer entry to the v0.16.0 changelog section
partylikeits1983 Aug 12, 2026
bfbd161
refactor(tx): drop the AggLayer fee policy helpers from NetworkNotePr…
partylikeits1983 Aug 12, 2026
a12978b
Merge branch 'next' into ajl-agglayer-constant-fee-policy
partylikeits1983 Aug 12, 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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

### Features

- [BREAKING] AggLayer bridge and faucet accounts now take their fee policy manager at deployment, built by the new `NetworkNotePricer::agglayer_bridge_fee_policy_manager` / `agglayer_faucet_fee_policy_manager` ([#3487](https://github.com/0xMiden/protocol/issues/3487)).
- [BREAKING] AggLayer bridge and faucet accounts install the `ConstantFeeManager` so their `ADMIN` role can reprice the deployed fee schedule; the faucet is now `Authority::RbacControlled` and its constructors take a deployment admin ([#3487](https://github.com/0xMiden/protocol/issues/3487)).
Comment thread
partylikeits1983 marked this conversation as resolved.
Outdated
- [BREAKING] The AggLayer bridge now accepts `RbacConfigNote`s, enabling on-chain rotation of its `ADMIN`, `FAUCET_MNGR`, `GER_INJECTOR`, and `GER_REMOVER` roles; the `create_existing_bridge_account_with_roles` testing fixture now takes the `ADMIN` member explicitly ([#2706](https://github.com/0xMiden/protocol/issues/2706)).
- Added the `ConstantFeeManager` account component, exposing the authority-gated `set_note_fee` procedure to update a `BasicConstantFeePolicy`'s fee schedule on a network account after deployment; the supplied fee asset's ID is validated against the account's configured fee asset and its value word is validated to be a well-formed fungible amount not exceeding the maximum ([#3322](https://github.com/0xMiden/protocol/issues/3322)).
- Added the `miden-protocol-build-utils` crate with helpers to assemble MASM code ([#3334](https://github.com/0xMiden/protocol/pull/3334)).
Expand Down
96 changes: 89 additions & 7 deletions crates/miden-agglayer/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ implementation are called out inline with `TODO (Future)` markers.
| **AggLayer Faucet** | Fungible faucet that represents a single bridged token. Mints on bridge-in claims, burns on bridge-out. Each foreign token has its own faucet instance. | `FungibleFaucet`, network-mode, with `agglayer_faucet` component |
| **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 |
Comment thread
partylikeits1983 marked this conversation as resolved.
Outdated

---

Expand Down Expand Up @@ -255,7 +255,8 @@ so while the bridge is paused it rejects all bridge-out, claim, GER-injection, a
faucet-management operations. `remove_ger` is deliberately exempt: a paused bridge can still
revoke a fraudulent GER, and because `update_ger` is paused the revoked GER cannot be
re-injected until unpause. The management notes (`RBAC_CONFIG`, `NETWORK_ACCOUNT_CONFIG`,
`PAUSE_CONFIG`) remain consumable while paused, so a paused bridge can still be administered.
`PAUSE_CONFIG`, `CONSTANT_FEE_POLICY_CONFIG`) remain consumable while paused, so a paused bridge
can still be administered.

The pause is toggled via the standards [`PAUSE_CONFIG`](#411-pause_config-standards) note, which
dispatches to `PausableManager`'s `pause` / `unpause`. These have no entry in the bridge's
Expand All @@ -265,6 +266,39 @@ The pause complements the `Authority` freeze switch: freezing blocks every autho
procedure - including `remove_ger` - but not `claim` / `bridge_out`, while the pause is the
inverse.

#### Fee schedule administration

Both network accounts are deployed with a `BasicConstantFeePolicy` whose schedule prices every
note they can consume from that note's benchmarked consumption cost under the chain's
`FeeParameters` (`NetworkNotePricer::agglayer_bridge_fee_policy_manager` /
`agglayer_faucet_fee_policy_manager`). A schedule entry is a bare amount denominated in the
chain's fee asset, so it is only correct for the verification base fee it was priced under.

Because that base fee is a chain parameter which moves independently of these accounts, both
install the `miden-standards` `ConstantFeeManager` and allowlist the
[`CONSTANT_FEE_POLICY_CONFIG`](#412-constant_fee_policy_config-standards) note, which dispatches
to its `set_note_fee`. Neither account maps that procedure in its `Authority` procedure-to-role
map, so authorization falls back to the `ADMIN` role, exactly as for the pause toggles. Without
it a schedule would be frozen at its deployment prices for the account's whole lifetime.

Repricing the faucet matters as much as repricing the bridge. When the bridge creates a `MINT` or
`BURN` note it sizes that note's fee sponsorship by reading the *faucet's* schedule as a foreign
account, so a faucet left at stale prices makes the bridge under-sponsor the note it has just
created, and the faucet's transaction can no longer pay its own fee. A frozen faucet schedule
therefore stalls bridging, not merely faucet administration.

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.
Comment thread
partylikeits1983 marked this conversation as resolved.
Outdated

That reach is not hypothetical: a priced schedule requires every consumed note's fee to be
prepaid. A note whose schedule entry is non-zero can only be consumed together with
`FEE_SPONSORSHIP` notes bound to it that cover that entry, independently of the chain's own
verification base fee. Operators therefore fund a sponsorship alongside each management note
(`RBAC_CONFIG`, `NETWORK_ACCOUNT_CONFIG`, `PAUSE_CONFIG`), and repricing is the one
administrative action that never needs one.

---

## 3. Contracts and Public Interfaces
Expand Down Expand Up @@ -454,7 +488,8 @@ access-control components at account creation time.
### 3.2 Faucet Account Component

The faucet account has the `agglayer_faucet` component (`components/faucet.masm`),
which is a thin wrapper, on top of `Ownable2Step` + `OwnerControlled`, that re-exports the
which is a thin wrapper, on top of `Ownable2Step` + the RBAC access-control stack
(`RoleBasedAccessControl` + `Authority::RbacControlled`), that re-exports the
standard Miden fungible-faucet procedures:

- `mint_and_send` (from `miden::standards::faucets::fungible::mint_and_send`)
Expand Down Expand Up @@ -501,12 +536,25 @@ This is a re-export of `miden::standards::faucets::fungible::receive_and_burn`.
|-----------|-----------|----------------|---------|
| Faucet metadata (standard) | Value | `[token_supply, max_supply, decimals, token_symbol]` | Standard `NetworkFungibleFaucet` metadata |

**Companion component storage slots:** The faucet account also includes storage from
companion components required by `fungible::mint_and_send`:
**Companion component storage slots:** The faucet account also includes storage from its
companion components - those required by `fungible::mint_and_send`, plus the access-control and
fee-administration stack:

- `Ownable2Step` owner config slot: stores the bridge account ID as owner.
- `OwnerControlled` slots (3): `active_policy_proc_root`, `allowed_policy_proc_roots`,
`policy_authority`.
- `TokenPolicyManager` slots: `active_policy_proc_root`, `allowed_policy_proc_roots` per policy
kind.
- `RoleBasedAccessControl` role storage, seeded with the deployment `ADMIN` member, and the
`Authority` config slot (`RbacControlled`) with an empty procedure-to-role map.
- `ConstantFeeManager` value slot: the ID of the fee schedule slot it reprices.

**Access control:** minting and burning are gated on the `Ownable2Step` owner (the bridge), which
`MintOwnerOnly` / `BurnOwnerOnly` assert directly via `ownable2step::assert_sender_is_owner`
rather than through `Authority`. Everything else on the faucet - its fee schedule, its mint / burn
/ transfer policies and its metadata - is authority-gated and so resolves to the `ADMIN` role
through the unmapped-procedure fallback. The two authorities are therefore separate: `ADMIN`
administers the faucet's configuration without being able to mint, and the bridge mints without
being able to reconfigure. Note that `ADMIN` can retarget the `Ownable2Step` owner, so it must be
held by a strongly authenticated account (see [Section 1](#1-entities-and-trust-model)).

---

Expand Down Expand Up @@ -1092,6 +1140,40 @@ with clearer error reporting for non-public targets.

---

### 4.12 CONSTANT_FEE_POLICY_CONFIG (standards)

**Purpose:** Reprices one entry of a network account's `BasicConstantFeePolicy` fee schedule
after deployment (see [Section 2.5](#25-administration)). This is the `miden-standards`
`CONSTANT_FEE_POLICY_CONFIG` note (`constant_fee_policy_config.masm` /
`ConstantFeePolicyConfigNote`), not an agglayer-specific note; both the bridge and the faucet
include its script root in their allowlists. Its storage is
`[NOTE_SCRIPT_ROOT, FEE_ASSET_ID, FEE_ASSET_VALUE]`: the schedule key to rewrite, and the fee to
schedule for it.

**Consumption:** The script asserts the consuming account matches its `NetworkAccountTarget`
attachment, then `call`s `ConstantFeeManager::set_note_fee`, which runs
`authority::assert_authorized` before writing the schedule entry. The supplied asset's ID must
match the account's configured fee asset ID. On both AggLayer accounts `set_note_fee` has no
mapped role, so the note sender must hold the `ADMIN` role.

`set_note_fee` carries no `pausable::assert_not_paused`, so a paused bridge can still be
repriced, consistent with the other management notes.

Because the note is allowlisted and scheduled free, anyone can author one targeting either
account; unauthorized or misdirected notes abort at the target and authorization checks with no
state change, but since the transaction aborts no nullifier is produced and such notes remain as
permanently-unconsumable entries that may require operator-side filtering. This is inherent to
every allowlisted network-note root, not specific to this note.

#### Permissions

| Role | Enforcement |
|------|------------|
| **Issuer** | Holders of the `ADMIN` role only -- **enforced** by `ConstantFeeManager::set_note_fee` via `authority::assert_authorized` (unmapped-procedure fallback) |
| **Consumer** | Bridge or faucet account -- **enforced**: the script asserts the consuming account matches the `NetworkAccountTarget` attachment |

---

## 5. Amount Conversion

*This section is a placeholder. Content to be added.*
Expand Down
30 changes: 22 additions & 8 deletions crates/miden-agglayer/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@ use miden_protocol_build_utils::{
generate_error_file,
};
use miden_standards::StandardsLib;
use miden_standards::account::access::{AccessControl, Authority, Pausable, PausableManager};
use miden_standards::account::access::{AccessControl, Pausable, PausableManager};
use miden_standards::account::auth::AuthNetworkAccount;
use miden_standards::account::fees::{BasicConstantFeePolicy, FeePolicyManager};
use miden_standards::account::fees::{
BasicConstantFeePolicy,
ConstantFeeManager,
FeePolicyManager,
};
use miden_standards::account::policies::{
BurnPolicy,
MintPolicy,
Expand Down Expand Up @@ -188,12 +192,12 @@ fn generate_agglayer_constants(
AccountComponent::new(Arc::unwrap_or_clone(package), vec![], dummy_metadata.clone())
.unwrap();

// The faucet account includes Ownable2Step and OwnerControlled components for mint and burn
// policies alongside the agglayer faucet component, since
// fungible::mint_and_send requires these for access control.
// The faucet account includes an Ownable2Step component alongside the agglayer faucet
// component, since fungible::mint_and_send gates minting on the owner, plus the RBAC
// access-control stack that gates everything else.
//
// Use a dummy owner for commitment computation - the actual owner is set at runtime. Only
// the component code (not storage) contributes to the code commitment.
// Use a dummy owner and admin for commitment computation - the real ones are set at
// runtime. Only the component code (not storage) contributes to the code commitment.
let dummy_owner = miden_protocol::account::AccountId::try_from(
miden_protocol::testing::account_id::ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE,
)
Expand Down Expand Up @@ -231,11 +235,19 @@ fn generate_agglayer_constants(
});
components.push(AccountComponent::from(Pausable::unpaused()));
components.push(AccountComponent::from(PausableManager));
components
.push(AccountComponent::from(ConstantFeeManager::for_basic_constant_fee_policy()));
} else if component_name == "faucet" {
components.push(AccountComponent::from(
miden_standards::account::access::Ownable2Step::new(dummy_owner),
));
components.push(AccountComponent::from(Authority::OwnerControlled));
// The faucet installs the same RBAC access-control stack as the bridge, so its
// ADMIN role can reprice the fee schedule and administer its policies. Minting and
// burning remain gated on the Ownable2Step owner, which the policies check directly.
components.extend(AccessControl::Rbac {
admin: dummy_owner,
procedure_roles: std::collections::BTreeMap::new(),
});
// Mirror the component order used by `create_agglayer_faucet_builder` in lib.rs so
// the compile-time code commitment matches the one computed at runtime.
//
Expand All @@ -251,6 +263,8 @@ fn generate_agglayer_constants(
.build();

components.extend(token_policy_manager);
components
.push(AccountComponent::from(ConstantFeeManager::for_basic_constant_fee_policy()));
}

// use `AccountCode` to merge codes of agglayer and authentication components
Expand Down
21 changes: 18 additions & 3 deletions crates/miden-agglayer/src/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ use miden_protocol::errors::NoteError;
use miden_protocol::note::{Note, NoteScriptRoot};
#[cfg(any(feature = "testing", test))]
use miden_standards::account::access::PausableStorage;
use miden_standards::account::auth::AuthNetworkAccount;
use miden_standards::note::{
ConstantFeePolicyConfigNote,
NetworkAccountTarget,
NetworkAccountTargetError,
NoteExecutionHint,
Expand Down Expand Up @@ -471,11 +473,13 @@ impl AggLayerBridge {
/// means any transaction consuming a note outside this set is rejected before reaching
/// `output_note::create`.
///
/// Besides the agglayer-specific notes, the bridge accepts two standards notes: the
/// [`PauseConfigNote`], so the `ADMIN` role can toggle the emergency pause, and the
/// Besides the agglayer-specific notes, the bridge accepts three standards notes: the
/// [`PauseConfigNote`], so the `ADMIN` role can toggle the emergency pause, the
/// role-management [`RbacConfigNote`], which makes the bridge's RBAC role graph mutable
/// on-chain (see the [`RbacConfigNote`] security considerations and the Administration
/// section of `SPEC.md` for the associated caveats).
/// section of `SPEC.md` for the associated caveats), and the
/// [`ConstantFeePolicyConfigNote`], so the `ADMIN` role can reprice the bridge's fee
/// schedule after deployment (see [`Self::fee_policy_notes`]).
///
/// [`AuthNetworkAccount`]: miden_standards::account::auth::AuthNetworkAccount
pub fn allowed_notes() -> BTreeSet<NoteScriptRoot> {
Expand All @@ -488,9 +492,20 @@ impl AggLayerBridge {
RemoveGerNote::script_root(),
PauseConfigNote::script_root(),
RbacConfigNote::script_root(),
ConstantFeePolicyConfigNote::script_root(),
])
}

/// Returns every input-note script root whose fee must be scheduled on an AggLayer bridge.
///
/// This is the bridge's explicit allowlist plus the configuration and sponsorship notes that
/// [`AuthNetworkAccount`] adds to every standard network account.
pub fn fee_policy_notes() -> BTreeSet<NoteScriptRoot> {
Comment thread
partylikeits1983 marked this conversation as resolved.
Outdated
let mut notes = Self::allowed_notes();
notes.extend(AuthNetworkAccount::default_allowed_note_scripts());
notes
}

// PAUSE NOTE
// --------------------------------------------------------------------------------------------

Expand Down
27 changes: 23 additions & 4 deletions crates/miden-agglayer/src/faucet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use miden_protocol::asset::{AssetAmount, TokenSymbol};
use miden_protocol::errors::AccountIdError;
use miden_protocol::note::NoteScriptRoot;
use miden_standards::account::access::{Authority, Ownable2Step};
use miden_standards::account::auth::AuthNetworkAccount;
use miden_standards::account::faucets::{FungibleFaucet, FungibleFaucetError, TokenName};
use miden_standards::account::policies::TokenPolicyManager;
pub use miden_standards::interop::eth::{
Expand All @@ -20,7 +21,7 @@ pub use miden_standards::interop::eth::{
EthAmountError,
EthEmbeddedAccountId,
};
use miden_standards::note::{BurnNote, MintNote};
use miden_standards::note::{BurnNote, ConstantFeePolicyConfigNote, MintNote};
use thiserror::Error;

use super::agglayer_faucet_component_package;
Expand Down Expand Up @@ -153,12 +154,30 @@ impl AggLayerFaucet {

/// Returns the set of input-note script roots that AggLayer faucet accounts accept.
///
/// The faucet's [`AuthNetworkAccount`] component is initialized with this allowlist so only
/// MINT and BURN notes can drive the faucet.
/// The faucet's [`AuthNetworkAccount`] component is initialized with this allowlist, so the
/// faucet is driven only by MINT and BURN notes plus the [`ConstantFeePolicyConfigNote`]
/// through which the `ADMIN` role reprices its fee schedule after deployment. The bridge
/// sizes the sponsorship of every MINT and BURN note it creates from that schedule, so a
/// schedule frozen at its deployment prices stalls bridging as soon as the chain's
/// verification base fee moves.
///
/// [`AuthNetworkAccount`]: miden_standards::account::auth::AuthNetworkAccount
pub fn allowed_notes() -> BTreeSet<NoteScriptRoot> {
BTreeSet::from([MintNote::script_root(), BurnNote::script_root()])
BTreeSet::from([
MintNote::script_root(),
BurnNote::script_root(),
ConstantFeePolicyConfigNote::script_root(),
])
}

/// Returns every input-note script root whose fee must be scheduled on an AggLayer faucet.
///
/// This is the faucet's explicit allowlist plus the configuration and sponsorship notes that
/// [`AuthNetworkAccount`] adds to every standard network account.
pub fn fee_policy_notes() -> BTreeSet<NoteScriptRoot> {
let mut notes = Self::allowed_notes();
notes.extend(AuthNetworkAccount::default_allowed_note_scripts());
notes
}

/// Extracts the underlying [`FungibleFaucet`] component (which holds the token metadata)
Expand Down
Loading
Loading