-
Notifications
You must be signed in to change notification settings - Fork 125
feat(standards): add flexible Burn Policies for Regulated Fungible Tokens #2664
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
onurinanc
wants to merge
10
commits into
0xMiden:next
Choose a base branch
from
onurinanc:burn-policies
base: next
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
0d0bab2
add burn policies
onurinanc 5f83f68
changelog
onurinanc dd98e91
merge next
onurinanc 384d1a0
fix comments
onurinanc c372e8c
refactor OwnerControlled and AuthControlled
onurinanc 75b2bd9
Merge branch 'next' into burn-policies
onurinanc 191004a
Merge branch 'next' into burn-policies
onurinanc 993f49f
review fix
onurinanc da85160
move slots to a shared location
onurinanc a2f20cd
Merge remote-tracking branch 'origin/burn-policies' into burn-policies
onurinanc File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
crates/miden-standards/asm/account_components/burn_policies/auth_controlled.masm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # The MASM code of the Burn Policy Auth Controlled Account Component. | ||
| # | ||
| # See the `BurnAuthControlled` Rust type's documentation for more details. | ||
|
|
||
| pub use ::miden::standards::burn_policies::allow_all | ||
| pub use ::miden::standards::burn_policies::policy_manager::set_burn_policy | ||
| pub use ::miden::standards::burn_policies::policy_manager::get_burn_policy |
11 changes: 11 additions & 0 deletions
11
crates/miden-standards/asm/account_components/burn_policies/owner_controlled.masm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # The MASM code of the Burn Policy Owner Controlled Account Component. | ||
| # | ||
| # See the `OwnerControlled` Rust type's documentation for more details. | ||
|
|
||
| # Re-export `allow_all` from `miden::standards::burn_policies` so the | ||
| # faucet can switch the active burn policy to allow-all via `set_burn_policy`. | ||
| # The auth-controlled component uses the same standards procedure. | ||
| pub use ::miden::standards::burn_policies::allow_all | ||
| pub use ::miden::standards::burn_policies::owner_controlled::owner_only | ||
| pub use ::miden::standards::burn_policies::policy_manager::set_burn_policy | ||
| pub use ::miden::standards::burn_policies::policy_manager::get_burn_policy |
4 changes: 2 additions & 2 deletions
4
crates/miden-standards/asm/account_components/mint_policies/auth_controlled.masm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| # The MASM code of the Mint Policy Auth Controlled Account Component. | ||
| # | ||
| # See the `AuthControlled` Rust type's documentation for more details. | ||
| # See the `MintAuthControlled` Rust type's documentation for more details. | ||
|
|
||
| pub use ::miden::standards::mint_policies::auth_controlled::allow_all | ||
| pub use ::miden::standards::mint_policies::allow_all | ||
| pub use ::miden::standards::mint_policies::policy_manager::set_mint_policy | ||
| pub use ::miden::standards::mint_policies::policy_manager::get_mint_policy |
14 changes: 14 additions & 0 deletions
14
crates/miden-standards/asm/standards/burn_policies/mod.masm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # Generic burn policy procedures shared by policy manager flows. | ||
|
|
||
| # POLICY PROCEDURES | ||
| # ================================================================================================ | ||
|
|
||
| #! Burn policy that accepts every burn request. | ||
| #! | ||
| #! Inputs: [ASSET_KEY, ASSET_VALUE] | ||
| #! Outputs: [] | ||
| #! Invocation: dynexec | ||
| pub proc allow_all | ||
| dropw dropw | ||
| # => [] | ||
| end |
21 changes: 21 additions & 0 deletions
21
crates/miden-standards/asm/standards/burn_policies/owner_controlled.masm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| use miden::standards::access::ownable2step | ||
|
|
||
| # POLICY PROCEDURES | ||
| # ================================================================================================ | ||
|
|
||
| #! Owner-only burn predicate. | ||
| #! | ||
| #! Inputs: [ASSET_KEY, ASSET_VALUE] | ||
| #! Outputs: [] | ||
| #! | ||
| #! Panics if: | ||
| #! - note sender is not owner. | ||
| #! | ||
| #! Invocation: dynexec | ||
| pub proc owner_only | ||
| exec.ownable2step::assert_sender_is_owner | ||
| # => [ASSET_KEY, ASSET_VALUE] | ||
|
|
||
| dropw dropw | ||
| # => [] | ||
| end |
207 changes: 207 additions & 0 deletions
207
crates/miden-standards/asm/standards/burn_policies/policy_manager.masm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,207 @@ | ||
| use miden::core::word | ||
| use miden::protocol::active_account | ||
| use miden::protocol::native_account | ||
| use miden::standards::access::ownable2step | ||
|
|
||
| # DEPENDENCY NOTE | ||
| # This manager supports two policy-authority modes: | ||
| # - 0: auth_controlled: no Ownable2Step dependency. | ||
| # - 1: owner_controlled: requires Ownable2Step component | ||
| # (`ownable2step::assert_sender_is_owner`) for `set_burn_policy`. | ||
|
|
||
| # CONSTANTS | ||
| # ================================================================================================ | ||
|
|
||
| # Active policy root slot. | ||
| # Layout: [PROC_ROOT] | ||
| const ACTIVE_POLICY_PROC_ROOT_SLOT=word("miden::standards::burn_policy_manager::active_policy_proc_root") | ||
|
|
||
| # Allowlist map slot for policy roots. | ||
| # Map entries: [PROC_ROOT] -> [1, 0, 0, 0] | ||
| const ALLOWED_POLICY_PROC_ROOTS_SLOT=word("miden::standards::burn_policy_manager::allowed_policy_proc_roots") | ||
|
|
||
| # Policy authority slot. | ||
| # Layout: [policy_authority, 0, 0, 0] | ||
| # - POLICY_AUTHORITY = 0: policy authority rely on `auth_controlled`. | ||
| # - POLICY_AUTHORITY = 1: `set_burn_policy` requires Ownable2Step owner check. | ||
| const POLICY_AUTHORITY_SLOT=word("miden::standards::burn_policy_manager::policy_authority") | ||
| const POLICY_AUTHORITY_OWNER_CONTROLLED=1 | ||
|
|
||
| # Local memory pointer used to pass a policy root to `dynexec`. | ||
| const BURN_POLICY_PROC_ROOT_PTR=0 | ||
|
|
||
| # ERRORS | ||
| # ================================================================================================ | ||
|
|
||
| const ERR_BURN_POLICY_ROOT_IS_ZERO="burn policy root is zero" | ||
| const ERR_BURN_POLICY_ROOT_NOT_IN_ACCOUNT="burn policy root is not a procedure of this account" | ||
| const ERR_BURN_POLICY_ROOT_NOT_ALLOWED="burn policy root is not allowed" | ||
|
|
||
| # INTERNAL PROCEDURES | ||
| # ================================================================================================ | ||
|
|
||
| #! Reads active burn policy root from storage. | ||
| #! | ||
| #! Inputs: [] | ||
| #! Outputs: [BURN_POLICY_ROOT] | ||
| #! | ||
| #! Invocation: exec | ||
| proc get_burn_policy_root | ||
| push.ACTIVE_POLICY_PROC_ROOT_SLOT[0..2] exec.active_account::get_item | ||
| # => [BURN_POLICY_ROOT] | ||
| end | ||
|
|
||
| #! Validates policy root before use. | ||
| #! | ||
| #! Inputs: [BURN_POLICY_ROOT] | ||
| #! Outputs: [BURN_POLICY_ROOT] | ||
| #! | ||
| #! Panics if: | ||
| #! - policy root is zero. | ||
| #! - policy root is not present in this account's procedures. | ||
| #! | ||
| #! Invocation: exec | ||
| proc assert_existing_policy_root | ||
| exec.word::testz | ||
| assertz.err=ERR_BURN_POLICY_ROOT_IS_ZERO | ||
| # => [BURN_POLICY_ROOT] | ||
|
|
||
| dupw exec.active_account::has_procedure | ||
| assert.err=ERR_BURN_POLICY_ROOT_NOT_IN_ACCOUNT | ||
| # => [BURN_POLICY_ROOT] | ||
| end | ||
|
|
||
| #! Validates that the policy root is one of the allowed policy roots configured for this account. | ||
| #! | ||
| #! Inputs: [BURN_POLICY_ROOT] | ||
| #! Outputs: [BURN_POLICY_ROOT] | ||
| #! | ||
| #! Panics if: | ||
| #! - policy root is not in the allowed policy roots map. | ||
| #! | ||
| #! Invocation: exec | ||
| proc assert_allowed_policy_root | ||
| dupw | ||
| push.ALLOWED_POLICY_PROC_ROOTS_SLOT[0..2] | ||
| exec.active_account::get_map_item | ||
| # => [ALLOWED_FLAG, BURN_POLICY_ROOT] | ||
|
|
||
| exec.word::eqz | ||
| assertz.err=ERR_BURN_POLICY_ROOT_NOT_ALLOWED | ||
| # => [BURN_POLICY_ROOT] | ||
| end | ||
|
|
||
| #! Reads policy authority mode. | ||
| #! - 0 = `auth_controlled` | ||
| #! - 1 = `owner_controlled` | ||
| #! | ||
| #! Inputs: [] | ||
| #! Outputs: [policy_authority] | ||
| #! | ||
| #! Invocation: exec | ||
| proc get_policy_authority | ||
| push.POLICY_AUTHORITY_SLOT[0..2] exec.active_account::get_item | ||
| # => [policy_authority, 0, 0, 0] | ||
|
|
||
| movdn.3 | ||
| # => [0, 0, 0, policy_authority] | ||
|
|
||
| drop drop drop | ||
| # => [policy_authority] | ||
| end | ||
|
|
||
| #! Authorizes policy update based on policy authority mode. | ||
| #! | ||
| #! `OwnerControlled` uses Ownable2Step directly rather than delegating | ||
| #! authorization to the active burn policy through dynexec. Delegating to the active | ||
| #! policy would allow a permissive policy (e.g. allow-all) to let any caller change | ||
| #! which burn policy root is active. | ||
| #! | ||
| #! Inputs: [NEW_POLICY_ROOT] | ||
| #! Outputs: [NEW_POLICY_ROOT] | ||
| #! | ||
| #! Panics if: | ||
| #! - POLICY_AUTHORITY = 1 and the sender is not owner. | ||
| #! | ||
| #! Invocation: exec | ||
| proc assert_can_set_burn_policy | ||
| exec.get_policy_authority | ||
| # => [policy_authority, NEW_POLICY_ROOT] | ||
|
|
||
| eq.POLICY_AUTHORITY_OWNER_CONTROLLED | ||
| if.true | ||
| exec.ownable2step::assert_sender_is_owner | ||
| # => [NEW_POLICY_ROOT] | ||
| end | ||
| end | ||
|
PhilippGackstatter marked this conversation as resolved.
|
||
|
|
||
| # PUBLIC INTERFACE | ||
| # ================================================================================================ | ||
|
|
||
| #! Executes active burn policy for the provided asset by dynamic execution. | ||
| #! | ||
| #! Inputs: [ASSET_KEY, ASSET_VALUE] | ||
| #! Outputs: [] | ||
| #! | ||
| #! Panics if: | ||
| #! - burn policy root is invalid. | ||
| #! - active burn policy validation fails. | ||
| #! | ||
| #! Invocation: exec | ||
| @locals(4) | ||
| pub proc execute_burn_policy | ||
| exec.get_burn_policy_root | ||
| # => [BURN_POLICY_ROOT, ASSET_KEY, ASSET_VALUE] | ||
|
|
||
| exec.assert_existing_policy_root | ||
| # => [BURN_POLICY_ROOT, ASSET_KEY, ASSET_VALUE] | ||
|
|
||
| exec.assert_allowed_policy_root | ||
| # => [BURN_POLICY_ROOT, ASSET_KEY, ASSET_VALUE] | ||
|
|
||
| loc_storew_le.BURN_POLICY_PROC_ROOT_PTR dropw | ||
| # => [ASSET_KEY, ASSET_VALUE] | ||
|
|
||
| locaddr.BURN_POLICY_PROC_ROOT_PTR | ||
| # => [policy_root_ptr, ASSET_KEY, ASSET_VALUE] | ||
|
|
||
| dynexec | ||
| # => [] | ||
| end | ||
|
|
||
| #! Returns active burn policy root. | ||
| #! | ||
| #! Inputs: [pad(16)] | ||
| #! Outputs: [BURN_POLICY_ROOT, pad(12)] | ||
| #! | ||
| #! Invocation: call | ||
| pub proc get_burn_policy | ||
| exec.get_burn_policy_root | ||
| # => [BURN_POLICY_ROOT, pad(12)] | ||
| end | ||
|
|
||
| #! Sets active burn policy root. | ||
| #! | ||
| #! Inputs: [NEW_POLICY_ROOT, pad(12)] | ||
| #! Outputs: [pad(16)] | ||
| #! | ||
| #! Panics if: | ||
| #! - POLICY_AUTHORITY = 1 and the sender is not owner. | ||
| #! - NEW_POLICY_ROOT is zero. | ||
| #! - NEW_POLICY_ROOT is not a procedure of this account. | ||
| #! - NEW_POLICY_ROOT is not in the allowed roots map. | ||
| #! | ||
| #! Invocation: call | ||
| pub proc set_burn_policy | ||
| exec.assert_can_set_burn_policy | ||
| # => [NEW_POLICY_ROOT, pad(12)] | ||
|
|
||
| exec.assert_existing_policy_root | ||
| # => [NEW_POLICY_ROOT, pad(12)] | ||
|
|
||
| exec.assert_allowed_policy_root | ||
| # => [NEW_POLICY_ROOT, pad(12)] | ||
|
|
||
| push.ACTIVE_POLICY_PROC_ROOT_SLOT[0..2] exec.native_account::set_item dropw | ||
| # => [pad(16)] | ||
| end | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Judging by this comment (#2724 (comment)), this may have to be
BurnOwnerControlled::owner_only(). Maybe @mmagician can double check.