You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently P2ID notes allow sending assets to an account ID, but require the recipient to cover the transaction fee. This leads to poor UX when users receive a note but lack the native-fee tokens to consume it. P2IDS improves this by bundling a fee asset with the note.
P2IDS addresses two UX challenges:
automatic consumption of notes in a wallet
claiming friction when sending payment notes with non-native asset to a new wallet
Automatic consumption of notes in a wallet
The Miden Wallet currently is configured to auto-consume notes carrying the native Miden token (from our official faucet). It would be desirable if wallets could do this safely for all assets.
One reason wallets shouldn't be configured to simply auto-consume all P2ID notes is the risk of griefing. An attacker could spam a user with P2ID notes that the wallet always claims, forcing the user's account to pay fees each time. The user would lose fee tokens on junk notes / memecoins*.
Note that the current auto-consumption of Miden native token is also at the risk of griefing once fees are turned on: the attacker could send a note with the minimal denomination of the native token, yet still triggering note consumption and the payment of a fee.**
Claiming friction
The existing P2ID notes allow sending assets directly to a specific account, but require the recipient to pay the consumption fee themselves. This creates a poor UX for users who have no native fee token in their vault and thus cannot claim the note without first acquiring funds for fees. This is cumbersome for payments, testnet faucets or airdrops.
P2IDS standard
The P2IDS note type addresses this by bundling a fee payment within the note itself. This lets wallets automatically consume such notes on the user's behalf without pre-funding.
With P2IDS, not only is the receiving of payments a no-click experience ✅ , but the griefing attack is mitigated as well: the wallet can be configured to auto-consume only P2IDS notes, knowing that they're safe to consume and would not drain the user's balance. The sender (sponsor) of the note bears the fee cost upfront.
The remaining edge-case is if network fees spike such that the included fee asset is insufficient to cover the consumption. In that case, the wallet might have to dip into the user's funds, or the transaction may fail if the user has no extra funds. This scenario can be mitigated by over-funding the fee asset, or by the wallet checking coverage(see also footnote **) before auto-consumption.
Design
A P2ID note can already carry multiple assets, but there is no enforcement on which tokens & amounts are included.
In contrast, a P2IDS note would check that (under the network conditions at the time of note creation) it would be consumable "for free", i.e. the native asset it carries is enough to cover the fees.
Pseudo-MASM Script
begin
# Current P2ID logic
# ...
# --------- Sponsored-note specific logic ----------
# Get the number of assets
push.0 exec.active_note::get_assets
# => [num_assets, ...]
exec.estimate_consumption_fee
# => [estimated_consumption_fee]
# Get the native asset, and assert that its value is at least `estimated_consumption_fee`
# ...
# --------------------------------------------------
exec.basic_wallet::add_assets_to_account
# => []
end
#! Estimate the fee required to consume the P2IDS note given the number of assets it carries.
#!
#! The number of cycles is estimated offchain.
#! It's probably going to be some base complexity + a variable factor proportional to the number of assets.
#!
#! The returned fee should be sufficient to cover the actual
#! verification cost under **current** network parameters.
#!
#! Inputs: [num_assets]
#! Outputs: [fee_amount]
const PER_ASSET_NUM_CYCLES = 42
const BASE_NUM_CYCLES = 100
proc estimate_consumption_fee
push.PER_ASSET_NUM_CYCLES mul push.BASE_NUM_CYCLES add
# => [num_cycles]
# Get the current base fee
exec.memory::get_verification_base_fee # <----- need to expose this in miden-lib
# => [verification_base_fee, num_cycles]
mul
# => [fee_amount]
end
*Since our fee mechanism isn'f fully designed yet, one way of reducing the surface for a griefing attack would be to make sure consuming a note is always cheaper than creating one, but this has many intricacies: it's not purely the Note DB & Nullifier DB update fees that matter, but also the account updates triggered by the production/consumption of such notes. This wouldn't eliminate the griefing attack, but would further disincentivize attacker, effectively forcing the attacker to incur a strictly higher cost than the victim.
**The wallet could easily specify logic such as: only consume if the fee < received asset. But this still doesn't cover the case for non-native tokens (w/o dependance on an oracle).
Open questions
what are the best mechanisms to mitigate the scenarios when network fees change?
should this be applied to P2IDE(S) notes as well?
can we design the fee mechanism s.t. it best supports P2IDS (i.e. with the goal of minimizing the cases when the fee asset is not sufficient)? This would be worthy of its own discussion, but here are some rough ideas:
a multi-dimensional fee mechanism with a {non/less} variable component that P2IDS could benefit from (e.g., nullifying a note has a rather fixed cost, creating a note is more variable)
a secondary, stable fee asset
the P2IDS note could carry a fixed portion of the stable fee asset, plus the target token
the network actions (account update, nullifier tree update, etc.) would have a fixed cost denominated in the secondary asset, but acquiring the secondary fee token is proportionally costly (due to market conditions or via an in-protocol swapping mechanism) to the network load
the network actions may also be paid for in the primary token
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Currently P2ID notes allow sending assets to an account ID, but require the recipient to cover the transaction fee. This leads to poor UX when users receive a note but lack the native-fee tokens to consume it. P2IDS improves this by bundling a fee asset with the note.
P2IDS addresses two UX challenges:
Automatic consumption of notes in a wallet
The Miden Wallet currently is configured to auto-consume notes carrying the native Miden token (from our official faucet). It would be desirable if wallets could do this safely for all assets.
One reason wallets shouldn't be configured to simply auto-consume all P2ID notes is the risk of griefing. An attacker could spam a user with P2ID notes that the wallet always claims, forcing the user's account to pay fees each time. The user would lose fee tokens on junk notes / memecoins*.
Note that the current auto-consumption of Miden native token is also at the risk of griefing once fees are turned on: the attacker could send a note with the minimal denomination of the native token, yet still triggering note consumption and the payment of a fee.**
Claiming friction
The existing P2ID notes allow sending assets directly to a specific account, but require the recipient to pay the consumption fee themselves. This creates a poor UX for users who have no native fee token in their vault and thus cannot claim the note without first acquiring funds for fees. This is cumbersome for payments, testnet faucets or airdrops.
P2IDS standard
The P2IDS note type addresses this by bundling a fee payment within the note itself. This lets wallets automatically consume such notes on the user's behalf without pre-funding.
With P2IDS, not only is the receiving of payments a no-click experience ✅ , but the griefing attack is mitigated as well: the wallet can be configured to auto-consume only P2IDS notes, knowing that they're safe to consume and would not drain the user's balance. The sender (sponsor) of the note bears the fee cost upfront.
The remaining edge-case is if network fees spike such that the included fee asset is insufficient to cover the consumption. In that case, the wallet might have to dip into the user's funds, or the transaction may fail if the user has no extra funds. This scenario can be mitigated by over-funding the fee asset, or by the wallet checking coverage(see also footnote **) before auto-consumption.
Design
A P2ID note can already carry multiple assets, but there is no enforcement on which tokens & amounts are included.
In contrast, a P2IDS note would check that (under the network conditions at the time of note creation) it would be consumable "for free", i.e. the native asset it carries is enough to cover the fees.
Pseudo-MASM Script
*Since our fee mechanism isn'f fully designed yet, one way of reducing the surface for a griefing attack would be to make sure consuming a note is always cheaper than creating one, but this has many intricacies: it's not purely the Note DB & Nullifier DB update fees that matter, but also the account updates triggered by the production/consumption of such notes. This wouldn't eliminate the griefing attack, but would further disincentivize attacker, effectively forcing the attacker to incur a strictly higher cost than the victim.
**The wallet could easily specify logic such as: only consume if the fee < received asset. But this still doesn't cover the case for non-native tokens (w/o dependance on an oracle).
Open questions
Original discussion: https://midengroup.slack.com/archives/C096TBZM686/p1767965226823219
All reactions