Skip to content

Flexible Minting Policies for Token Standards#2559

Open
onurinanc wants to merge 34 commits into0xMiden:nextfrom
onurinanc:onur-mint-policies
Open

Flexible Minting Policies for Token Standards#2559
onurinanc wants to merge 34 commits into0xMiden:nextfrom
onurinanc:onur-mint-policies

Conversation

@onurinanc
Copy link
Contributor

This PR corresponds to the discussion for Miden Token Standards, overall, it implements flexible and modular minting policies: OpenZeppelin/miden-confidential-contracts#39

Design specification related to this document: OpenZeppelin/miden-confidential-contracts#39 (comment)

Please see additional design discussion here: OpenZeppelin/miden-confidential-contracts#39 (reply in thread)

#! Distributes freshly minted fungible assets to the provided recipient.
#!
#! Invocation: call
pub proc distribute
   exec.mint_policies::enforce_mint_policy # previously -> exec.ownable::verify_owner
   # => [amount, tag, aux, note_type, execution_hint, RECIPIENT, pad(7)]

   exec.faucets::distribute
   # => [note_idx, pad(15)]
end

[ ] Left to-do: I would like to rename this procedure as pub proc mint as we have discussed with @bobbinth but I would like to double-check is there any other thoughts on this?

@bobbinth bobbinth requested review from PhilippGackstatter, bobbinth and mmagician and removed request for PhilippGackstatter and mmagician March 6, 2026 06:03
Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Looks good! Thank you! Not a full review yet - but I left some comments inline. The main comment so far is about splitting the component into a "policy manager" component and separate policy components (probably just a single policy component for now).

#!
#! Invocation: exec
proc assert_valid_policy_root
dupw exec.word::eqz
Copy link
Contributor

Choose a reason for hiding this comment

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

We could use word::testz procedure here to avoid the dupw.

exec.active_account::get_map_item
# => [ALLOWED_FLAG, MINT_POLICY_ROOT]

dupw exec.word::eqz not
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as above.

Comment on lines +9 to +12
const MINT_POLICY_PROC_ROOT_SLOT=word("miden::standards::mint_policies::proc_root")
const MINT_POLICY_PARAMS_SLOT=word("miden::standards::mint_policies::params")
const MINT_POLICY_ALLOWED_ROOTS_SLOT=word("miden::standards::mint_policies::allowed_roots")
const MINT_POLICY_PROC_ROOT_PTR=0
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be good to add some comments explaining the purpose and expected formats of the storage slots. For example, it is not immediately clear what "allowed roots" means.

@onurinanc
Copy link
Contributor Author

All done! Please review: @bobbinth

@onurinanc onurinanc requested a review from bobbinth March 9, 2026 17:08
Copy link
Contributor

@PhilippGackstatter PhilippGackstatter left a comment

Choose a reason for hiding this comment

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

Looks good to me!

I left a few comments related to naming and structure, e.g. whether it should be MintPolicies or MintPolicyManager.

# See the `BasicFungibleFaucet` Rust type's documentation for more details.

pub use ::miden::standards::faucets::basic_fungible::distribute
pub use ::miden::standards::faucets::basic_fungible::mint
Copy link
Contributor

Choose a reason for hiding this comment

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

That's a very welcome change 🙂

Since this does both minting (like miden::protocol::faucet::mint), but also creating a note, maybe we should consider mint_to_note as the name to reflect the note creation side effect in the name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@PhilippGackstatter I think the intent of mint_to_note is good but instead what about having mint_and_create_note which semantically sounds better?

Copy link
Contributor

Choose a reason for hiding this comment

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

That's a bit more explicit and also a good choice. Another one might be mint_and_send (saw it in OpenZeppelin/miden-confidential-contracts#79 (comment)) which is a bit more concise but less explicit (does not mention note).

Copy link
Contributor

@bobbinth bobbinth Mar 12, 2026

Choose a reason for hiding this comment

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

I like mint_and_send - though, not a very strong preference.

And, in a future PR, we could also add a regular mint procedure which mints an asset and adds it to the account's vault.

Comment on lines 28 to 29
pub proc distribute
pub proc mint
exec.faucets::distribute
Copy link
Contributor

Choose a reason for hiding this comment

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

The faucets::distribute should probably also be renamed to mint, right?

#! - note sender is not owner.
#!
#! Invocation: dynexec
pub proc mint_policy_owner_only
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: It might be sufficient to name this owner_only, since the module is called mint_policies already, so the module-qualified name would be mint_policies::owner_only which reads naturally.

Comment on lines +9 to +11
# Active policy root slot.
# Layout: [proc_root_w0, proc_root_w1, proc_root_w2, proc_root_w3]
const MINT_POLICY_PROC_ROOT_SLOT=word("miden::standards::mint_policies::proc_root")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# Active policy root slot.
# Layout: [proc_root_w0, proc_root_w1, proc_root_w2, proc_root_w3]
const MINT_POLICY_PROC_ROOT_SLOT=word("miden::standards::mint_policies::proc_root")
# Active policy root slot.
# Layout: [PROC_ROOT]
const MINT_POLICY_PROC_ROOT_SLOT=word("miden::standards::mint_policies::proc_root")

Nit: Avoid specifying the individual word elements.

Comment on lines +77 to +82
exec.word::testz not
assert.err=ERR_MINT_POLICY_ROOT_NOT_ALLOWED
# => [ALLOWED_FLAG, MINT_POLICY_ROOT]

dropw
# => [MINT_POLICY_ROOT]
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: We can avoid the dropw by simplifying to word::eqz not assert (or assertz directly).

Comment on lines +53 to +56
#[derive(Debug, Clone, Copy)]
pub struct MintPolicies {
initial_policy_root: Word,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be called MintPolicyManager and the mint_policies_library be renamed to mint_policy_manager_library along with crates/miden-standards/asm/account_components/faucets/mint_policies.masm?

I'd also suggest renaming MintPolicyConfig -> MintPolicy so we can "instantiate a mint policy manager with a mint policy".

Comment on lines +146 to +163
let allowed_roots =
if mint_policies.initial_policy_root == MintPolicies::owner_only_policy_root() {
StorageMap::with_entries([(
StorageMapKey::from_raw(MintPolicies::owner_only_policy_root()),
Word::from([1u32, 0, 0, 0]),
)])
} else {
StorageMap::with_entries([
(
StorageMapKey::from_raw(MintPolicies::owner_only_policy_root()),
Word::from([1u32, 0, 0, 0]),
),
(
StorageMapKey::from_raw(mint_policies.initial_policy_root),
Word::from([1u32, 0, 0, 0]),
),
])
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Consider introducing a constant or variable that represents the "allowed flag" (word [1,0,0,0]).

Comment on lines +145 to +151
let mut rng = RpoRandomCoin::new([Felt::from(rng_seed); 4].into());
let note = NoteBuilder::new(sender_account_id, &mut rng)
.note_type(NoteType::Private)
.tag(NoteTag::default().into())
.serial_number(Word::from([rng_seed, rng_seed + 1, rng_seed + 2, rng_seed + 3]))
.code(note_script_code)
.build()?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
let mut rng = RpoRandomCoin::new([Felt::from(rng_seed); 4].into());
let note = NoteBuilder::new(sender_account_id, &mut rng)
.note_type(NoteType::Private)
.tag(NoteTag::default().into())
.serial_number(Word::from([rng_seed, rng_seed + 1, rng_seed + 2, rng_seed + 3]))
.code(note_script_code)
.build()?;
let mut rng = RpoRandomCoin::new([Felt::from(rng_seed); 4].into());
let note = NoteBuilder::new(sender_account_id, &mut rng)
.note_type(NoteType::Private)
.code(note_script_code)
.build()?;

Nit: The serial number is generated by the RNG internally and the note tag should already be set to its default by the builder.

The NoteBuilder can also compile a string itself so no need to use CodeBuilder above.


let tx_context = mock_chain
.build_tx_context(faucet_id, &[], &[note])?
.add_note_script(note_script)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
.add_note_script(note_script)

Nit: Haven't checked but this is likely unnecessary.

Comment on lines +752 to +755
/// Tests owner minting on a network faucet built from two separate components:
/// `NetworkFungibleFaucet` and `MintPolicies`.
#[tokio::test]
async fn test_network_faucet_owner_can_mint_with_separate_mint_policies_component()
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this test effectively testing additional things than the other tests that use a network fungible faucet with MintPolicyConfig::OwnerOnly? I think it doesn't and if so, I'd remove it.

Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Looks good! Thank you! Not a full review still, but I left some comments inline.

Comment on lines +88 to +91
#! Enforces active mint policy by dynamic execution.
#!
#! Inputs: [amount, tag, note_type, RECIPIENT, pad(9)]
#! Outputs: [amount, tag, note_type, RECIPIENT, pad(9)]
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the motivation here is that we create a note right after calling this procedure, and so, duplicating all note inputs would be a bit wasteful. I don't really have a strong preference here.

But it does make me think that this procedure is specifically related to sending notes. So, maybe the name here should reflect this? Something like enforce_mint_and_send_policy?

#! - active policy predicate fails.
#!
#! Invocation: exec
pub proc enforce_mint_policy
Copy link
Contributor

Choose a reason for hiding this comment

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

I actually don't mind enforce_ prefix, but also don't have anything against the execute_ prefix.

.storage_mode(AccountStorageMode::Network)
.with_auth_component(auth_component)
.with_component(NetworkFungibleFaucet::new(symbol, decimals, max_supply, owner_account_id)?)
.with_component(MintPolicies::new(mint_policy_config))
Copy link
Contributor

Choose a reason for hiding this comment

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

Once we have the Ownable2Step component, we'd need to add it here too, right?

@onurinanc
Copy link
Contributor Author

onurinanc commented Mar 12, 2026

Thank you for the review, all done! @bobbinth @PhilippGackstatter Please review.

Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Looks great! Thank you! I think we are pretty close. I left some more comments inline. The main one is about potentially making MintPolicyManager into a stand-alone component. We could also decide to do it in a follow-up PR to merge this PR sooner.

#! Invocation: exec
@locals(4)
pub proc distribute
pub proc mint_and_send
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I'd probably update the comment on line 38 above a bit as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not for this PR, but we should probably think about allowing updates to policy allowlist (i.e., adding or removing policies). Should be pretty easy to do - we'd probably need something like add_allowed_policy and remove_allowed_policy procedures.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe this would be a parallel work to upgradable/updatable contracts. The main reason is that, even if we provide adding/removing allowed policies, if the account code is not upgradable, this won't make any sense since the corresponding code won't be the part of the account. This is the main reason why I didn't include updating the allowed policies in this PR. That means, when upgrading the account code, the user can also update the allowed policies. So, I think that there is no need for updating the allowed policies.

Comment on lines +31 to +32
# Keep this procedure digest distinct from network_fungible::mint_and_send.
push.0 drop
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need to do this?

Copy link
Contributor Author

@onurinanc onurinanc Mar 16, 2026

Choose a reason for hiding this comment

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

@bobbinth The main problem is that when both NetworkFungibleFaucet and BasicFungibleFaucet have the same procedure digest (without having push.0 drop, both mint_and_send and burn will have the same procedure digests), and AccountComponentInterface::try_from is not able to differentiate those components, and we're having MissingNetworkFungibleFaucetInterface as the account component interface matches with BasicFungibleFaucet. We didn't have this problem before they produced different procedure digests. @PhilippGackstatter do you have any suggestion on this?

The first and the most basic solution is keeping the procedure digests different as adding push.0 drop
The second one is refactoring AccountComponentInterface

So, I would like to keep it simple for now, and you could potentially refactor the AccountComponentInterface

Copy link
Contributor

Choose a reason for hiding this comment

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

I think that's an okay workaround for now, as we plan to remove the AccountComponentInterface as it is and then this problem would naturally go away. It would be good to leave a TODO: Remove once AccountComponentInterface is refactored here, though.

Copy link
Contributor

Choose a reason for hiding this comment

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

I would mention somewhere in the comments at the top of the file that this component requires the policy manager component to also be in the account.

Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as above re mentioning the policy manager dependency.

Comment on lines +5 to +7
pub use ::miden::standards::mint_policies::auth_tx_controlled::allow_all
pub use ::miden::standards::mint_policies::policy_manager::set_mint_policy
pub use ::miden::standards::mint_policies::policy_manager::get_mint_policy
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as above.

Comment on lines 289 to 295
pub fn create_network_fungible_faucet(
init_seed: [u8; 32],
symbol: TokenSymbol,
decimals: u8,
max_supply: Felt,
access_control: AccessControl,
) -> Result<Account, FungibleFaucetError> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not for this PR, but we should probably make this take TokenMetadata instead of passing in symbol, decimals, and max_supply separately.

Copy link
Contributor Author

@onurinanc onurinanc Mar 16, 2026

Choose a reason for hiding this comment

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

I think TokenMetadata PR should address this one but if not I'll be addressing in the follow-up PR.

@@ -300,6 +301,7 @@
.with_auth_component(auth_component)
.with_component(NetworkFungibleFaucet::new(symbol, decimals, max_supply)?)
.with_component(access_control)
Copy link
Contributor

Choose a reason for hiding this comment

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

Before getting here, we should validate that access_control is Ownable2Step. I know this is the only variant right now, but as we add variants in the future, this could change. And since we here depend on Ownable2Step - we should make sure we check it.

.with_description(
"Mint policy owner controlled component for network fungible faucets",
)
.with_storage_schema(storage_schema);
Copy link
Contributor

Choose a reason for hiding this comment

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

In other places, we started to encapsulate this into a separate method. For example, here it could be:

impl OwnerControlled {

    pub fn component_metadata() -> AccountComponentMetadata {
        let storage_schema = StorageSchema::new(vec![
            OwnerControlled::active_policy_proc_root_slot_schema(),
            OwnerControlled::allowed_policy_proc_roots_slot_schema(),
            OwnerControlled::policy_authority_slot_schema(),
        ])
        .expect("storage schema should be valid");

        AccountComponentMetadata::new(OwnerControlled::NAME, [AccountType::FungibleFaucet])
            .with_description(
                "Mint policy owner controlled component for network fungible faucets",
            )
            .with_storage_schema(storage_schema);
    }
}

And then here, this becomes just:

let metadata = OwnerControlled::component_metadata();

Comment on lines +59 to +61
pub struct AuthTxControlled {
initial_policy_root: Word,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm wondering if the naming here is accurate - specifically the AuthTx part. Technically, we have authentication procedures - so, this could be AuthProcControlled - but I wonder if just AuthControlled is sufficient.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think AuthTxControlled constitutes a good naming but all the naming of the auth component account starts with pub proc auth_tx. However, AuthControlled would be a candidate since the owner-controlled one is basically NoAuth. But, there is also current change, which we specify the auth component procedures as @authscript, so maybe AuthScriptControlled, so I've found naming this one quite confusing.
CC: @PhilippGackstatter

@onurinanc onurinanc requested a review from bobbinth March 16, 2026 11:53
Copy link
Contributor

@PhilippGackstatter PhilippGackstatter left a comment

Choose a reason for hiding this comment

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

Looks good to me!

I'll approve since most of my comments apply to follow-ups.

Comment on lines +5 to +7
pub use ::miden::standards::mint_policies::owner_controlled::owner_only
pub use ::miden::standards::mint_policies::policy_manager::set_mint_policy
pub use ::miden::standards::mint_policies::policy_manager::get_mint_policy
Copy link
Contributor

Choose a reason for hiding this comment

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

Generally agreed that it seems better to have a base MintPolicyManager component that can be extended in plug & play fashion with additional mint policy components.

Not a strong opinion whether we should do it in this PR or later.

Comment on lines +36 to 42
pub proc mint_and_send
exec.policy_manager::execute_mint_policy
# => [new_amount, new_tag, new_note_type, NEW_RECIPIENT, pad(9)]

exec.faucets::distribute
exec.faucets::mint_and_send
# => [note_idx, pad(15)]
end
Copy link
Contributor

Choose a reason for hiding this comment

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

The code of NetworkFungibleFaucet and BasicFungibleFaucet is now identical, so I think we should collapse these into just one type, i.e. BasicFungibleFaucet.

The difference between a network and a "local" faucet is now just a different configuration of the overall account, but the distinction no longer exists at the account component level, and so we don't need different code and account components.

If agreed, we should create an issue as a follow-up. This could also make the token metadata #2439 simpler.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Overall, I agree we should address this issue, but I'm not sure if we should to this in a follow-up PR or wait a bit more if there would be a specific needs for the NetworkFungibleFaucet in the future so that we don't need to re-implement it again.


# Allowlist map slot for policy roots.
# Map entries: [PROC_ROOT] -> [1, 0, 0, 0]
# This slot ensure `dynexec` runs only allowed mint-policy roots, not arbitrary procedures.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# This slot ensure `dynexec` runs only allowed mint-policy roots, not arbitrary procedures.
# This slot ensures the policy manager runs only allowed mint-policy roots, not arbitrary procedures.

Nit: I'd rephrase this

const ALLOWED_POLICY_PROC_ROOTS_SLOT=word("miden::standards::mint_policy_manager::allowed_policy_proc_roots")

# Policy authority slot.
# Layout: [POLICY_AUTHORITY, 0, 0, 0]
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# Layout: [POLICY_AUTHORITY, 0, 0, 0]
# Layout: [policy_authority, 0, 0, 0]

Nit: felts are lowercase

Comment on lines +93 to +98
exec.word::testz
assertz.err=ERR_MINT_POLICY_ROOT_NOT_ALLOWED
# => [ALLOWED_FLAG, MINT_POLICY_ROOT]

dropw
# => [MINT_POLICY_ROOT]
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: This could be word::eqz assertz to avoid the dropw.

#!
#! Invocation: exec
@locals(4)
pub proc execute_mint_policy
Copy link
Contributor

Choose a reason for hiding this comment

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

This procedure validates the mint policy, but get_mint_policy does not. Depending on the perspective, both are valid approaches:

  • We can say that since set_mint_policy validates the procedure when setting, so the stored mint policy is valid.
  • The only exception to the above is that the account deployer could set an invalid root, and so we could also say that we should always validate the mint policy on retrieval.

So far, I think we have usually used the first approach, though this was mostly for component-internal data. I'm not sure how much damage a malicious deployer could do by setting an invalid mint policy root, probably not much other than making their own account unusable, so I'd go with approach 1.

This makes me wish we could let every account component have some on-chain validation of its storage at account creation time so we could always go with the first approach and provide stronger guarantees.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this is a good point! I agree that we would have stronger guarantees with on-chain validation, but it also adds more complexity for account creation, and this also needs an execution order design and rules between the other account components. I'm not exactly sure which one is the right direction.

// [num_trigger_procs, allow_unauthorized_output_notes, allow_unauthorized_input_notes, 0].
//
// With 1 trigger procedure (distribute), allow_unauthorized_output_notes=false, and
// With 1 trigger procedure (mint), allow_unauthorized_output_notes=false, and
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// With 1 trigger procedure (mint), allow_unauthorized_output_notes=false, and
// With 1 trigger procedure (mint_and_send), allow_unauthorized_output_notes=false, and


// The procedure root map should contain the distribute procedure root.
let distribute_root = BasicFungibleFaucet::distribute_digest();
// The procedure root map should contain the mint procedure root.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// The procedure root map should contain the mint procedure root.
// The procedure root map should contain the mint_and_send procedure root.

Comment on lines +192 to +195
let policy_authority_slot = StorageSlot::with_value(
AuthControlled::policy_authority_slot().clone(),
Word::from([0u32, 0, 0, 0]),
);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should introduce an enum for the policy authority, because it's otherwise hard to understand which zero represents the actual config and what that zero represents. Something like:

#[repr(u8)]
pub enum MintPolicyAuthority {
    AuthControlled = 0,
    OwnerControlled = 1,
}

impl From<MintPolicyAuthority> for StorageSlot { ... }

impl AuthControlled {
    pub fn mint_policy_authority(&self) -> MintPolicyAuthority {
        MintPolicyAuthority::AuthControlled
    }
}

And then here we'd have:

let policy_authority_slot = StorageSlot::from(auth_controlled.mint_policy_authority);

Comment on lines +32 to +43
static ACTIVE_MINT_POLICY_PROC_ROOT_SLOT_NAME: LazyLock<StorageSlotName> = LazyLock::new(|| {
StorageSlotName::new("miden::standards::mint_policy_manager::active_policy_proc_root")
.expect("storage slot name should be valid")
});
static ALLOWED_MINT_POLICY_PROC_ROOTS_SLOT_NAME: LazyLock<StorageSlotName> = LazyLock::new(|| {
StorageSlotName::new("miden::standards::mint_policy_manager::allowed_policy_proc_roots")
.expect("storage slot name should be valid")
});
static POLICY_AUTHORITY_SLOT_NAME: LazyLock<StorageSlotName> = LazyLock::new(|| {
StorageSlotName::new("miden::standards::mint_policy_manager::policy_authority")
.expect("storage slot name should be valid")
});
Copy link
Contributor

Choose a reason for hiding this comment

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

These definitions are duplicated in crates/miden-standards/src/account/mint_policies/auth_controlled.rs, would be great to deduplicate, but also fine to do as part of the MintPolicyManager refactor.

The "miden::standards::mint_policy_manager::policy_authority" slot could be defined on the previously proposed MintPolicyAuthority enum.

@onurinanc
Copy link
Contributor Author

All done! The corresponding issues for the follow-up PRs are opened! @bobbinth @PhilippGackstatter

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants