Skip to content
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
- Added `component_metadata()` to all account components to expose their metadata ([#2596](https://github.com/0xMiden/protocol/pull/2596)).
- Added `Package` support in `MockChainBuilder` & `NoteScript` ([#2502](https://github.com/0xMiden/protocol/pull/2502)).
- Added `ProgramExecutor` hooks to support DAP and other custom transaction program executors ([#2574](https://github.com/0xMiden/protocol/pull/2574)).
- [BREAKING] Changed `native_account::remove_asset` to return the asset value remaining in the vault instead of the removed value ([#2626](https://github.com/0xMiden/protocol/pull/2626)).
- Implement `TransactionEventId::event_name` and `Host::resolve_event` for better VM diagnostics during even handler failures ([#2628](https://github.com/0xMiden/protocol/pull/2628)).
- Added `FixedWidthString` for fixed-width UTF-8 string storage in `miden-standards` (`miden::standards::utils::string`). ([#2633](https://github.com/0xMiden/protocol/pull/2633))

Expand Down Expand Up @@ -98,12 +99,13 @@
- Added Ownable2Step as an Account Component ([#2572](https://github.com/0xMiden/protocol/pull/2572))
- [BREAKING] Introduced `PrivateNoteHeader` for output notes and removed `RawOutputNote::Header` variant ([#2569](https://github.com/0xMiden/protocol/pull/2569)).
- [BREAKING] Changed `asset::create_fungible_asset` and `faucet::create_fungible_asset` signature to take `enable_callbacks` flag ([#2571](https://github.com/0xMiden/protocol/pull/2571)).

- [BREAKING] Fixed `TokenSymbol::try_from(Felt)` to reject values below `MIN_ENCODED_VALUE`; implemented `Display` for `TokenSymbol` replacing the fallible `to_string()` method; removed `Default` derive ([#2464](https://github.com/0xMiden/protocol/issues/2464)).
- Moved `AccountSchemaCommitment` component into a sub-module ([#2603](https://github.com/0xMiden/protocol/pull/2603)).
- Added foreign account ID assertion in `account::load_foreign_account` ([#2560](https://github.com/0xMiden/protocol/pull/2560)).
- [BREAKING] `AssetVault::remove_asset` returns the asset value remaining in the vault `Option<Asset>` rather than the removed value `Asset` ([#2626](https://github.com/0xMiden/protocol/pull/2626)).
- [BREAKING] `miden::protocol::faucet::burn` no longer returns the burnt asset value ([#2626](https://github.com/0xMiden/protocol/pull/2626)).
- Fixed overlap in initial and active account storage slot memory region ([#2557](https://github.com/0xMiden/protocol/pull/2557)).
- Fixed link map entry pointer validation bypass ([#2556](https://github.com/0xMiden/protocol/pull/2556)).
- Added foreign account ID assertion in `account::load_foreign_account` ([#2560](https://github.com/0xMiden/protocol/pull/2560)).

## 0.13.3 (2026-01-27)

Expand Down
13 changes: 7 additions & 6 deletions crates/miden-protocol/asm/kernels/transaction/api.masm
Original file line number Diff line number Diff line change
Expand Up @@ -583,14 +583,15 @@ pub proc account_add_asset
# => [ASSET_VALUE', pad(12)]
end

#! Removes the specified asset from the vault.
#! Removes the specified asset from the vault and returns the remaining asset value.
#!
#! Inputs: [ASSET_KEY, ASSET_VALUE, pad(8)]
#! Outputs: [ASSET_VALUE, pad(12)]
#! Outputs: [REMAINING_ASSET_VALUE, pad(12)]
#!
#! Where:
#! - ASSET_KEY is the vault key of the asset to remove from the vault.
#! - ASSET_VALUE is the value of the asset to remove from the vault.
#! - REMAINING_ASSET_VALUE is the value of the asset remaining in the vault after removal.
#!
#! Panics if:
#! - the fungible asset is not found in the vault.
Expand All @@ -610,7 +611,7 @@ pub proc account_remove_asset

# remove the specified asset from the account vault, emitting the corresponding events
exec.account::remove_asset_from_vault
# => [ASSET_VALUE, pad(12)]
# => [REMAINING_ASSET_VALUE, pad(12)]
end

#! Returns the asset associated with the provided asset vault key in the active account's vault.
Expand Down Expand Up @@ -780,11 +781,11 @@ end
#! Burn an asset from the faucet the transaction is being executed against.
#!
#! Inputs: [ASSET_KEY, ASSET_VALUE, pad(8)]
#! Outputs: [ASSET_VALUE, pad(12)]
#! Outputs: [pad(16)]
#!
#! Where:
#! - ASSET_KEY is the vault key of the asset to burn.
#! - ASSET_VALUE is the value of the asset that was burned.
#! - ASSET_VALUE is the value of the asset to burn.
#!
#! Panics if:
#! - the transaction is not being executed against a faucet.
Expand All @@ -810,7 +811,7 @@ pub proc faucet_burn_asset

# burn the asset
exec.faucet::burn
# => [ASSET_VALUE, pad(12)]
# => [pad(16)]
end

#! Returns whether the active account defines callbacks.
Expand Down
15 changes: 8 additions & 7 deletions crates/miden-protocol/asm/kernels/transaction/lib/account.masm
Original file line number Diff line number Diff line change
Expand Up @@ -742,14 +742,15 @@ pub proc add_asset_to_vault
# => [PROCESSED_ASSET_VALUE']
end

#! Removes the specified asset from the account vault.
#! Removes the specified asset from the account vault and returns the remaining asset value.
#!
#! Inputs: [ASSET_KEY, ASSET_VALUE]
#! Outputs: [ASSET_VALUE]
#! Outputs: [REMAINING_ASSET_VALUE]
#!
#! Where:
#! - ASSET_KEY is the asset vault key of the asset to remove from the vault.
#! - ASSET_VALUE is the value of the asset to remove from the vault.
#! - REMAINING_ASSET_VALUE is the value of the asset remaining in the vault after removal.
#!
#! Panics if:
#! - the fungible asset is not found in the vault.
Expand All @@ -770,17 +771,17 @@ pub proc remove_asset_from_vault

# remove the asset from the account vault
exec.asset_vault::remove_asset
# => [ASSET_VALUE, ASSET_KEY, ASSET_VALUE]
# => [REMAINING_ASSET_VALUE, ASSET_KEY, ASSET_VALUE]

swapw
# => [ASSET_KEY, ASSET_VALUE, ASSET_VALUE]
movdnw.2
# => [ASSET_KEY, ASSET_VALUE, REMAINING_ASSET_VALUE]

# emit event to signal that an asset is being removed from the account vault
emit.ACCOUNT_VAULT_AFTER_REMOVE_ASSET_EVENT
# => [ASSET_KEY, ASSET_VALUE, ASSET_VALUE]
# => [ASSET_KEY, ASSET_VALUE, REMAINING_ASSET_VALUE]

exec.account_delta::remove_asset
# => [ASSET_VALUE]
# => [REMAINING_ASSET_VALUE]
end

#! Returns the ASSET_VALUE associated with the provided asset vault key in the active account's vault.
Expand Down
84 changes: 35 additions & 49 deletions crates/miden-protocol/asm/kernels/transaction/lib/asset_vault.masm
Original file line number Diff line number Diff line change
Expand Up @@ -150,20 +150,8 @@ pub proc add_fungible_asset
padw loc_load.0 mem_loadw_le
# => [VAULT_ROOT, MERGED_ASSET_VALUE, ASSET_KEY, CUR_VAULT_VALUE, MERGED_ASSET_VALUE]

movdnw.2 padw
# => [EMPTY_WORD, MERGED_ASSET_VALUE, ASSET_KEY, VAULT_ROOT, CUR_VAULT_VALUE, MERGED_ASSET_VALUE]

# check if amount of new asset is zero
# if it is zero, insert EMPTY_WORD to keep the merkle tree sparse
dupw.1
exec.fungible_asset::value_into_amount
eq.0
# => [is_amount_zero, EMPTY_WORD, MERGED_ASSET_VALUE, ASSET_KEY, VAULT_ROOT, CUR_VAULT_VALUE, MERGED_ASSET_VALUE]

# If is_amount_zero EMPTY_WORD remains.
# If !is_amount_zero MERGED_ASSET_VALUE remains.
cdropw
# => [EMPTY_WORD_OR_MERGED_ASSET_VALUE, ASSET_KEY, VAULT_ROOT, CUR_VAULT_VALUE, MERGED_ASSET_VALUE]
movdnw.2
# => [MERGED_ASSET_VALUE, ASSET_KEY, VAULT_ROOT, CUR_VAULT_VALUE, MERGED_ASSET_VALUE]

# update asset in vault
exec.smt::set
Expand Down Expand Up @@ -261,21 +249,22 @@ end
# REMOVE ASSET
# =================================================================================================

#! Splits ASSET_VALUE off the existing asset in the vault associated with the ASSET_KEY.
#! Splits ASSET_VALUE off the existing asset in the vault associated with the ASSET_KEY
#! and returns the remaining asset value.
#!
#! For instance, if ASSET_KEY points to a fungible asset with amount 100, and ASSET_VALUE has
#! amount 30, then a fungible asset with amount 70 remains in the vault.
#! amount 30, then a fungible asset with amount 70 remains in the vault and is returned.
#!
#! Inputs: [ASSET_KEY, ASSET_VALUE, vault_root_ptr]
#! Outputs: [ASSET_VALUE]
#! Outputs: [REMAINING_ASSET_VALUE]
#!
#! Where:
#! - ASSET_KEY is the asset vault key of the fungible asset to remove from the vault.
#! - ASSET_VALUE is the fungible asset that was removed from the vault.
#! - REMAINING_ASSET_VALUE is the value of the fungible asset remaining in the vault after removal.
#! - vault_root_ptr is a pointer to the memory location at which the vault root is stored.
#!
#! Locals:
#! - 0..4: ASSET_VALUE
#! - 0..4: REMAINING_ASSET_VALUE
#!
#! Panics if:
#! - the amount of the asset in the vault is less than the amount to be removed.
Expand All @@ -293,33 +282,22 @@ pub proc remove_fungible_asset
movdnw.2
# => [ASSET_VALUE, ASSET_KEY, PEEKED_ASSET_VALUE, vault_root_ptr]

# store ASSET_VALUE so we can return it later
loc_storew_le.0
# => [ASSET_VALUE, ASSET_KEY, PEEKED_ASSET_VALUE, vault_root_ptr]

dupw.2 swapw
# => [ASSET_VALUE, PEEKED_ASSET_VALUE, ASSET_KEY, PEEKED_ASSET_VALUE, vault_root_ptr]

# compute PEEKED_ASSET_VALUE - ASSET_VALUE
# compute REMAINING_ASSET_VALUE = PEEKED_ASSET_VALUE - ASSET_VALUE
exec.fungible_asset::split
# => [NEW_ASSET_VALUE, ASSET_KEY, PEEKED_ASSET_VALUE, vault_root_ptr]

padw dupw.1 exec.fungible_asset::value_into_amount
# => [new_amount, EMPTY_WORD, NEW_ASSET_VALUE, ASSET_KEY, PEEKED_ASSET_VALUE, vault_root_ptr]

eq.0
# => [is_new_amount_zero, EMPTY_WORD, NEW_ASSET_VALUE, ASSET_KEY, PEEKED_ASSET_VALUE, vault_root_ptr]
# => [REMAINING_ASSET_VALUE, ASSET_KEY, PEEKED_ASSET_VALUE, vault_root_ptr]

# If is_new_amount_zero EMPTY_WORD remains.
# If !is_new_amount_zero NEW_ASSET_VALUE remains.
cdropw
# => [EMPTY_WORD_OR_NEW_ASSET_VALUE, ASSET_KEY, PEEKED_ASSET_VALUE, vault_root_ptr]
# store remaining asset value so we can return it later
loc_storew_le.0
# => [REMAINING_ASSET_VALUE, ASSET_KEY, PEEKED_ASSET_VALUE, vault_root_ptr]

dup.12 padw movup.4 mem_loadw_le
# => [VAULT_ROOT, EMPTY_WORD_OR_NEW_ASSET_VALUE, ASSET_KEY, PEEKED_ASSET_VALUE, vault_root_ptr]
# => [VAULT_ROOT, REMAINING_ASSET_VALUE, ASSET_KEY, PEEKED_ASSET_VALUE, vault_root_ptr]

movdnw.2
# => [EMPTY_WORD_OR_NEW_ASSET_VALUE, ASSET_KEY, VAULT_ROOT, PEEKED_ASSET_VALUE, vault_root_ptr]
# => [REMAINING_ASSET_VALUE, ASSET_KEY, VAULT_ROOT, PEEKED_ASSET_VALUE, vault_root_ptr]

# update asset in vault and assert the old value is equivalent to the peeked value provided
# via peek_asset
Expand All @@ -335,20 +313,23 @@ pub proc remove_fungible_asset
# => [NEW_VAULT_ROOT]

loc_loadw_le.0
# => [ASSET_VALUE]
# => [REMAINING_ASSET_VALUE]
end

#! Remove the specified non-fungible asset from the vault.
#! Remove the specified non-fungible asset from the vault and return the remaining asset value.
#!
#! Since non-fungible assets are either fully present or absent, the remaining value after
#! removal is always EMPTY_WORD.
#!
#! Note that the ASSET_VALUE is only needed to check against the asset that was removed from the
#! vault.
#!
#! Inputs: [ASSET_KEY, ASSET_VALUE, vault_root_ptr]
#! Outputs: [ASSET_VALUE]
#! Outputs: [REMAINING_ASSET_VALUE]
#!
#! Where:
#! - ASSET_KEY is the asset vault key of the non-fungible asset to remove from the vault.
#! - ASSET_VALUE is the non-fungible asset that was removed from the vault.
#! - REMAINING_ASSET_VALUE is always EMPTY_WORD (nothing remains after removing a non-fungible asset).
#! - vault_root_ptr is a pointer to the memory location at which the vault root is stored.
#!
#! Panics if:
Expand All @@ -366,22 +347,27 @@ pub proc remove_non_fungible_asset
exec.smt::set
# => [REMOVED_ASSET_VALUE, NEW_VAULT_ROOT, ASSET_VALUE, vault_root_ptr]

dupw.2 assert_eqw.err=ERR_VAULT_NON_FUNGIBLE_ASSET_TO_REMOVE_NOT_FOUND
# => [NEW_VAULT_ROOT, ASSET_VALUE, vault_root_ptr]
movupw.2 assert_eqw.err=ERR_VAULT_NON_FUNGIBLE_ASSET_TO_REMOVE_NOT_FOUND
# => [NEW_VAULT_ROOT, vault_root_ptr]

# update the vault root
movup.8 mem_storew_le dropw
# => [ASSET_VALUE]
movup.4 mem_storew_le dropw
# => []

# push EMPTY_WORD to represent that nothing remains after non-fungible removal
padw
# => [REMAINING_ASSET_VALUE]
end

#! Remove the specified asset from the vault.
#! Remove the specified asset from the vault and return the remaining asset value.
#!
#! Inputs: [ASSET_KEY, ASSET_VALUE, vault_root_ptr]
#! Outputs: [ASSET_VALUE]
#! Outputs: [REMAINING_ASSET_VALUE]
#!
#! Where:
#! - ASSET_KEY is the asset vault key of the asset to remove from the vault.
#! - ASSET_VALUE is the value of the asset to remove from the vault.
#! - REMAINING_ASSET_VALUE is the value of the asset remaining in the vault after removal.
#! - vault_root_ptr is a pointer to the memory location at which the vault root is stored.
#!
#! Panics if:
Expand All @@ -396,9 +382,9 @@ pub proc remove_asset
# remove the asset from the asset vault
if.true
exec.remove_fungible_asset
# => [ASSET_VALUE]
# => [REMAINING_ASSET_VALUE]
else
exec.remove_non_fungible_asset
# => [ASSET_VALUE]
# => [REMAINING_ASSET_VALUE]
end
end
28 changes: 18 additions & 10 deletions crates/miden-protocol/asm/kernels/transaction/lib/faucet.masm
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ end
#! against.
#!
#! Inputs: [ASSET_KEY, ASSET_VALUE]
#! Outputs: [ASSET_VALUE]
#! Outputs: []
#!
#! Where:
#! - ASSET_KEY is the vault key of the asset to burn.
#! - ASSET_VALUE is the value of the asset value to burn.
#! - ASSET_VALUE is the value of the asset to burn.
#!
#! Panics if:
#! - the transaction is not being executed against a fungible faucet.
Expand All @@ -67,7 +67,11 @@ proc burn_fungible_asset

# remove the asset from the input vault for asset preservation
exec.asset_vault::remove_fungible_asset
# => [ASSET_VALUE]
# => [REMAINING_ASSET_VALUE]

# drop the remaining value (not meaningful to the caller)
dropw
# => []
end

# NON-FUNGIBLE ASSETS
Expand Down Expand Up @@ -109,11 +113,11 @@ end
#! executed against.
#!
#! Inputs: [ASSET_KEY, ASSET_VALUE]
#! Outputs: [ASSET_VALUE]
#! Outputs: []
#!
#! Where:
#! - ASSET_KEY is the vault key of the asset to burn.
#! - ASSET_VALUE is the value of the asset value to burn.
#! - ASSET_VALUE is the value of the asset to burn.
#!
#! Panics if:
#! - the transaction is not being executed against a non-fungible faucet.
Expand All @@ -132,7 +136,11 @@ proc burn_non_fungible_asset
# => [ASSET_KEY, ASSET_VALUE, input_vault_root_ptr]

exec.asset_vault::remove_non_fungible_asset
# => [ASSET_VALUE]
# => [REMAINING_ASSET_VALUE]

# drop the remaining value (not meaningful to the caller)
dropw
# => []
end

# PUBLIC INTERFACE
Expand Down Expand Up @@ -177,11 +185,11 @@ end
#! Burn an asset from the faucet the transaction is being executed against.
#!
#! Inputs: [ASSET_KEY, ASSET_VALUE]
#! Outputs: [ASSET_VALUE]
#! Outputs: []
#!
#! Where:
#! - ASSET_KEY is the vault key of the asset to burn.
#! - ASSET_VALUE is the value of the asset value to burn.
#! - ASSET_VALUE is the value of the asset to burn.
#!
#! Panics if:
#! - the transaction is not being executed against a faucet.
Expand All @@ -200,10 +208,10 @@ pub proc burn
if.true
# burn the fungible asset
exec.burn_fungible_asset
# => [ASSET_VALUE]
# => []
else
# burn the non-fungible asset
exec.burn_non_fungible_asset
# => [ASSET_VALUE]
# => []
end
end
10 changes: 5 additions & 5 deletions crates/miden-protocol/asm/protocol/faucet.masm
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@ end
#! Burn an asset from the faucet the transaction is being executed against.
#!
#! Inputs: [ASSET_KEY, ASSET_VALUE]
#! Outputs: [ASSET_VALUE]
#! Outputs: []
#!
#! Where:
#! - ASSET_KEY is the vault key of the asset to burn.
#! - ASSET_VALUE is the value of the asset that was burned.
#! - ASSET_VALUE is the value of the asset to burn.
#!
#! Panics if:
#! - the transaction is not being executed against a faucet.
Expand All @@ -127,11 +127,11 @@ pub proc burn
# => [offset, ASSET_KEY, ASSET_VALUE, pad(7)]

syscall.exec_kernel_proc
# => [ASSET_VALUE, pad(12)]
# => [pad(16)]

# clean the stack
swapdw dropw dropw swapw dropw
# => [ASSET_VALUE]
dropw dropw dropw dropw
# => []
end

#! Returns whether the active account defines callbacks.
Expand Down
Loading
Loading