Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
- [BREAKING] Renamed `AccountProcedureInfo` into `AccountProcedureRoot` and remove storage offset and size ([#2162](https://github.com/0xMiden/miden-base/pull/2162)).
- [BREAKING] Made `AccountProcedureIndexMap` construction infallible ([#2163](https://github.com/0xMiden/miden-base/pull/2163)).
- [BREAKING] Renamed `tracked_procedure_roots_slot` to `trigger_procedure_roots_slot` in ACL auth components for naming consistency ([#2166](https://github.com/0xMiden/miden-base/pull/2166)).
- [BREAKING] Refactor `miden-objects` and `miden-lib` into `miden-protocol` and `miden-standards` ([#2184](https://github.com/0xMiden/miden-base/pull/2184), [#2191](https://github.com/0xMiden/miden-base/pull/2191), [#2197](https://github.com/0xMiden/miden-base/pull/2197)).
- [BREAKING] Refactor `miden-objects` and `miden-lib` into `miden-protocol` and `miden-standards` ([#2184](https://github.com/0xMiden/miden-base/pull/2184), [#2191](https://github.com/0xMiden/miden-base/pull/2191), [#2197](https://github.com/0xMiden/miden-base/pull/2197), [#2255](https://github.com/0xMiden/miden-base/pull/2255)).
- [BREAKING] Migrated to `miden-vm` v0.20 and `miden-crypto` v0.19 ([#2158](https://github.com/0xMiden/miden-base/pull/2158)).
- [BREAKING] Refactored `AccountStorageDelta` to use a new `StorageSlotDelta` type ([#2182](https://github.com/0xMiden/miden-base/pull/2182)).
- [BREAKING] Removed OLD_MAP_ROOT from being returned when calling [`native_account::set_map_item`](crates/miden-lib/asm/miden/native_account.masm) ([#2194](https://github.com/0xMiden/miden-base/pull/2194)).
Expand Down
27 changes: 2 additions & 25 deletions crates/miden-standards/asm/note_scripts/BURN.masm
Original file line number Diff line number Diff line change
@@ -1,28 +1,5 @@
use miden::standards::faucets
use miden::standards::notes::burn

#! BURN script: burns the asset from the note by calling the faucet's burn procedure.
#! This note can be executed against any faucet account that exposes the faucets::burn procedure
#! (e.g., basic fungible faucet or network fungible faucet).
#!
#! The burn procedure in the faucet already handles all necessary validations including:
#! - Checking that the note contains exactly one asset
#! - Verifying the asset is a fungible asset issued by this faucet
#! - Ensuring the amount to burn doesn't exceed the outstanding supply
#!
#! Requires that the account exposes:
#! - burn procedure (from the faucets interface).
#!
#! Inputs: [ARGS, pad(12)]
#! Outputs: [pad(16)]
#!
#! Panics if:
#! - account does not expose burn procedure.
#! - any of the validations in the burn procedure fail.
begin
dropw
# => [pad(16)]

# Call the faucet's burn procedure which handles all validations
call.faucets::burn
# => [pad(16)]
exec.burn::main
end
127 changes: 2 additions & 125 deletions crates/miden-standards/asm/note_scripts/MINT.masm
Original file line number Diff line number Diff line change
@@ -1,128 +1,5 @@
use miden::protocol::active_note
use miden::protocol::note
use miden::standards::faucets::network_fungible->network_faucet
use miden::standards::notes::mint

# CONSTANTS
# =================================================================================================

const MINT_NOTE_NUM_INPUTS_PRIVATE=8
const MINT_NOTE_MIN_NUM_INPUTS_PUBLIC=12

const OUTPUT_NOTE_TYPE_PUBLIC=1
const OUTPUT_NOTE_TYPE_PRIVATE=2

const OUTPUT_PUBLIC_NOTE_INPUTS_ADDR=12
const OUTPUT_PUBLIC_NOTE_INPUTS_LEN_MEM_ADDR=0

# ERRORS
# =================================================================================================
const ERR_MINT_WRONG_NUMBER_OF_INPUTS="MINT script expects exactly 8 inputs for private or 12+ inputs for public output notes"

#! Network Faucet MINT script: mints assets by calling the network faucet's distribute function.
#! This note is intended to be executed against a network fungible faucet account.
#!
#! Requires that the account exposes:
#! - miden::contracts::faucets::network_fungible::distribute procedure.
#!
#! Inputs: [ARGS, pad(12)]
#! Outputs: [pad(16)]
#!
#! Note inputs support two modes. Depending on the number of note inputs,
#! a private or public note is created on consumption of the MINT note:
#!
#! Private mode (8 inputs) - creates a private note:
#! - execution_hint: Execution hint for the output note
#! - aux: Auxiliary data for the output note
#! - tag: Note tag for the output note
#! - amount: The amount to mint
#! - RECIPIENT: The recipient digest (4 elements)
#!
#! Public mode (12+ inputs) - creates a public note with variable-length inputs:
#! - execution_hint: Execution hint for the output note
#! - aux: Auxiliary data for the output note
#! - tag: Note tag for the output note
#! - amount: The amount to mint
#! - SCRIPT_ROOT: Script root of the output note (4 elements)
#! - SERIAL_NUM: Serial number of the output note (4 elements)
#! - [INPUTS]: Variable-length inputs for the output note (Vec<Felt>)
#! The number of output note inputs = num_mint_note_inputs - 12
#!
#! Panics if:
#! - account does not expose distribute procedure.
#! - the number of inputs is not exactly 8 for private or less than 12 for public output notes.
begin
dropw
# => [pad(16)]
# Load note inputs into memory starting at address 0
push.0 exec.active_note::get_inputs
# => [total_inputs, inputs_ptr, pad(16)]

dup
# => [num_inputs, num_inputs, inputs_ptr, pad(16)]

u32assert2.err=ERR_MINT_WRONG_NUMBER_OF_INPUTS
u32gte.MINT_NOTE_MIN_NUM_INPUTS_PUBLIC
# => [is_public_output_note, total_inputs, inputs_ptr, pad(16)]

if.true
# public output note creation
# => [total_inputs, inputs_ptr, pad(16)]

movdn.9 drop
# => [EMPTY_WORD, EMPTY_WORD, total_inputs, pad(8)]

mem_loadw_be.4
# => [SCRIPT_ROOT, EMPTY_WORD, total_inputs, pad(8)]

swapw mem_loadw_be.8
# => [SERIAL_NUM, SCRIPT_ROOT, total_inputs, pad(8)]

# compute variable length note inputs for the output note
movup.8 sub.MINT_NOTE_MIN_NUM_INPUTS_PUBLIC
# => [num_output_note_inputs, SERIAL_NUM, SCRIPT_ROOT, pad(8)]

push.OUTPUT_PUBLIC_NOTE_INPUTS_ADDR
# => [inputs_ptr = 12, num_output_note_inputs, SERIAL_NUM, SCRIPT_ROOT, pad(8)]

exec.note::build_recipient
# => [RECIPIENT, pad(12)]

swapw mem_loadw_be.0
# => [amount, tag, aux, execution_hint, RECIPIENT, pad(8)]

push.OUTPUT_NOTE_TYPE_PUBLIC
# => [note_type, amount, tag, aux, execution_hint, RECIPIENT, pad(8)]

movdn.3
# => [amount, tag, aux, note_type, execution_hint, RECIPIENT, pad(8)]

else
# private output note creation

eq.MINT_NOTE_NUM_INPUTS_PRIVATE assert.err=ERR_MINT_WRONG_NUMBER_OF_INPUTS drop
# => [inputs_ptr, pad(16)]

drop
# => [pad(16)]

mem_loadw_be.4
# => [RECIPIENT, pad(12)]

swapw mem_loadw_be.0
# => [amount, tag, aux, execution_hint, RECIPIENT, pad(8)]

push.OUTPUT_NOTE_TYPE_PRIVATE
# => [note_type, amount, tag, aux, execution_hint, RECIPIENT, pad(8)]

movdn.3
# => [amount, tag, aux, note_type, execution_hint, RECIPIENT, pad(8)]

end
# => [amount, tag, aux, note_type, execution_hint, RECIPIENT, pad(8)]

call.network_faucet::distribute
# => [pad(17))]

drop
# => [pad(16)]
exec.mint::main
end
52 changes: 2 additions & 50 deletions crates/miden-standards/asm/note_scripts/P2ID.masm
Original file line number Diff line number Diff line change
@@ -1,53 +1,5 @@
use miden::protocol::active_account
use miden::protocol::account_id
use miden::protocol::active_note
use miden::standards::wallets::basic->basic_wallet
use miden::standards::notes::p2id

# ERRORS
# =================================================================================================

const ERR_P2ID_WRONG_NUMBER_OF_INPUTS="P2ID note expects exactly 2 note inputs"

const ERR_P2ID_TARGET_ACCT_MISMATCH="P2ID's target account address and transaction address do not match"

#! Pay-to-ID script: adds all assets from the note to the account, assuming ID of the account
#! matches target account ID specified by the note inputs.
#!
#! Requires that the account exposes:
#! - miden::contracts::wallets::basic::receive_asset procedure.
#!
#! Inputs: []
#! Outputs: []
#!
#! Note inputs are assumed to be as follows:
#! - target_account_id is the ID of the account for which the note is intended.
#!
#! Panics if:
#! - Account does not expose miden::contracts::wallets::basic::receive_asset procedure.
#! - Account ID of executing account is not equal to the Account ID specified via note inputs.
#! - The same non-fungible asset already exists in the account.
#! - Adding a fungible asset would result in amount overflow, i.e., the total amount would be
#! greater than 2^63.
begin
# store the note inputs to memory starting at address 0
padw push.0 exec.active_note::get_inputs
# => [num_inputs, inputs_ptr, EMPTY_WORD]

# make sure the number of inputs is 2
eq.2 assert.err=ERR_P2ID_WRONG_NUMBER_OF_INPUTS
# => [inputs_ptr, EMPTY_WORD]

# read the target account ID from the note inputs
mem_loadw_be drop drop
# => [target_account_id_prefix, target_account_id_suffix]

exec.active_account::get_id
# => [account_id_prefix, account_id_suffix, target_account_id_prefix, target_account_id_suffix, ...]

# ensure account_id = target_account_id, fails otherwise
exec.account_id::is_equal assert.err=ERR_P2ID_TARGET_ACCT_MISMATCH
# => []

exec.basic_wallet::add_assets_to_account
# => []
exec.p2id::main
end
143 changes: 2 additions & 141 deletions crates/miden-standards/asm/note_scripts/P2IDE.masm
Original file line number Diff line number Diff line change
@@ -1,144 +1,5 @@
use miden::protocol::active_account
use miden::protocol::account_id
use miden::protocol::active_note
use miden::protocol::tx
use miden::standards::wallets::basic->basic_wallet
use miden::standards::notes::p2ide

# ERRORS
# =================================================================================================

const ERR_P2IDE_WRONG_NUMBER_OF_INPUTS="P2IDE note expects exactly 4 note inputs"

const ERR_P2IDE_RECLAIM_ACCT_IS_NOT_SENDER="failed to reclaim P2IDE note because the reclaiming account is not the sender"

const ERR_P2IDE_RECLAIM_HEIGHT_NOT_REACHED="failed to reclaim P2IDE note because the reclaim block height is not reached yet"

const ERR_P2IDE_RECLAIM_DISABLED="P2IDE reclaim is disabled"

const ERR_P2IDE_TIMELOCK_HEIGHT_NOT_REACHED="failed to consume P2IDE note because the note is still timelocked"

# HELPER PROCEDURES
# =================================================================================================

#! Helper procedure to check if the P2IDE note is unlocked.
#!
#! Inputs: [current_block_height, timelock_block_height]
#! Outputs: [current_block_height]
proc verify_unlocked
dup movdn.2
# => [current_block_height, timelock_block_height, current_block_height]

# check timelock_block_height <= current_block_height
lte assert.err=ERR_P2IDE_TIMELOCK_HEIGHT_NOT_REACHED
# => [current_block_height]
end

#! Helper procedure which adds the note assets to the sender account.
#!
#! Checks if P2IDE reclaim is enabled and if true, if reclaim height has been reached.
#!
#! Inputs: [account_id_prefix, account_id_suffix, current_block_height, reclaim_block_height]
#! Outputs: []
#!
#! Panics if:
#! - the reclaim of the active note is disabled.
#! - the reclaim block height is not reached yet.
#! - the account attempting to reclaim the note is not the sender account.
proc reclaim_note
# check that the reclaim of the active note is enabled
movup.3 dup neq.0 assert.err=ERR_P2IDE_RECLAIM_DISABLED
# => [reclaim_block_height, account_id_prefix, account_id_suffix, current_block_height]

# now check that sender is allowed to reclaim, reclaim block height <= current block height
movup.3
# => [current_block_height, reclaim_block_height, account_id_prefix, account_id_suffix]

lte assert.err=ERR_P2IDE_RECLAIM_HEIGHT_NOT_REACHED
# => [account_id_prefix, account_id_suffix]

# if active account is not the target, we need to ensure it is the sender
exec.active_note::get_sender
# => [sender_account_id_prefix, sender_account_id_suffix, account_id_prefix, account_id_suffix]

# ensure active account ID = sender account ID
exec.account_id::is_equal assert.err=ERR_P2IDE_RECLAIM_ACCT_IS_NOT_SENDER
# => []

# add note assets to account
exec.basic_wallet::add_assets_to_account
# => []
end

#! Extended Pay-to-ID note script (Reclaimable & Timelockable)
#!
#! Adds all assets from the note to the account if all of the following conditions are true:
#! - The transaction's reference block number is greater than or equal to the note's timelock block height.
#! - Any of the following conditions is true:
#! - The account ID against which the transaction is executed matches the note's target account id.
#! - The account ID against which the transaction is executed matches the note's sender account id and
#! the transaction's reference block number is greater than or equal to the note's reclaim block height.
#!
#! Requires that the account exposes:
#! - miden::contracts::wallets::basic::receive_asset procedure.
#!
#! Inputs: []
#! Outputs: []
#!
#! Note inputs are assumed to be as follows:
#! - target_account_id is the ID of the account for which the note is intended.
#! - reclaim_block_height is the block height at which the note can be reclaimed by the sender.
#! - timelock_block_height is the block height at which the note can be consumed by the target.
#!
#! Panics if:
#! - The account does not expose miden::contracts::wallets::basic::receive_asset procedure.
#! - The note is consumed before the timelock expired, i.e. the transaction's reference block
#! number is less than the timelock block height.
#! - Before reclaim block height: the account ID of the executing account is not equal to the specified
#! account ID.
#! - At and after reclaim block height: the account ID of the executing account is not equal to
#! the specified account ID or sender account ID.
#! - The same non-fungible asset already exists in the account.
#! - Adding a fungible asset would result in an amount overflow, i.e., the total amount would be
#! greater than 2^63.
begin
# store the note inputs to memory starting at address 0
push.0 exec.active_note::get_inputs
# => [num_inputs, inputs_ptr]

# make sure the number of inputs is 4
eq.4 assert.err=ERR_P2IDE_WRONG_NUMBER_OF_INPUTS
# => [inputs_ptr]

# read the reclaim block height, timelock_block_height, and target account ID from the note inputs
mem_loadw_be
# => [timelock_block_height, reclaim_block_height, target_account_id_prefix, target_account_id_suffix]

# read the current block number
exec.tx::get_block_number
# => [current_block_height, timelock_block_height, reclaim_block_height, target_account_id_prefix, target_account_id_suffix]

# fails if note is locked
exec.verify_unlocked
# => [current_block_height, reclaim_block_height, target_account_id_prefix, target_account_id_suffix]

# get active account id
exec.active_account::get_id dup.1 dup.1
# => [account_id_prefix, account_id_suffix, account_id_prefix, account_id_suffix, current_block_height, reclaim_block_height, target_account_id_prefix, target_account_id_suffix]

# determine if the active account is the target account
movup.7 movup.7 exec.account_id::is_equal
# => [is_target, account_id_prefix, account_id_suffix, current_block_height, reclaim_block_height]

if.true
# we can safely consume the note since the active account is the target of the note
dropw exec.basic_wallet::add_assets_to_account
# => []

else
# checks if active account is sender and if reclaim is enabled
exec.reclaim_note
# => []
end

# => []
exec.p2ide::main
end
Loading