Skip to content

fix(standards): pin the fee payment to the native asset at 1-to-1 rate - #3808

Merged
bobbinth merged 4 commits into
nextfrom
mmagician-claude/pin-fee-to-native-asset
Sep 4, 2026
Merged

fix(standards): pin the fee payment to the native asset at 1-to-1 rate#3808
bobbinth merged 4 commits into
nextfrom
mmagician-claude/pin-fee-to-native-asset

Conversation

@mmagician

@mmagician mmagician commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Closes #3763, and replaces the bound-based approach of #3797 / #3798 / #3802 with a one-line assert.

Until we have support for fees in multiple tokens, this is approach fixes the issue. Once we have this support, the multisig fee payment would need refactoring anyway - so let's stick with the simplest approach now.

`fee::pay_fee` built the TX_FEE note from a caller-supplied conversion
info word and paid `ceil(fee_amount * rate_num / rate_den)` of the named
faucet's asset, checking neither the faucet nor the rate. Nothing
downstream re-checks the fee note either - the transaction epilogue and
the batch and block kernels contain no fee logic - so the authentication
procedure is the only place the paid amount is decided, and any
authorized transaction could move an arbitrary amount of an arbitrary
fungible asset out of the vault as a fee.

The conversion has nothing to convert: the computed fee is always
denominated in the chain's single native fee asset (`ProtocolConfig`,
verified against the reference block), and `verification_base_fee` is a
per-network constant copied from the parent block, so there is no
dynamic pricing either. Every production call site already commits
`FeeConversionInfo::one_to_one`.

`pay_fee` now asserts that the committed conversion info equals
`native_conversion_info`, which pins the payment faucet and the rate
together and makes the paid amount exactly the computed fee.

`convert_amount` stays public and keeps its coverage, moved to direct
invocation from a transaction script now that `pay_fee` only ever calls
it at 1/1.

Closes #3763.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0186Lb3N8KP4N75jFtWab3X6
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0186Lb3N8KP4N75jFtWab3X6
Comment thread crates/miden-standards/asm/standards/fee/mod.masm Outdated
Comment thread crates/miden-standards/asm/standards/fee/mod.masm Outdated
Comment thread crates/miden-standards/src/account/auth/fee.rs Outdated
Comment thread crates/miden-standards/src/account/auth/fee.rs Outdated
Comment thread crates/miden-standards/src/account/auth/singlesig.rs Outdated
Comment thread docs/src/fees.md Outdated
Comment thread docs/src/fees.md Outdated
Comment thread docs/src/transaction.md Outdated
Co-authored-by: Marti <marcin.gorny.94@protonmail.com>
@mmagician
mmagician requested a review from bobbinth September 4, 2026 15:14
@mmagician mmagician changed the title fix(standards): pin the fee payment to the native asset at par fix(standards): pin the fee payment to the native asset at 1-to-1 rate Sep 4, 2026
@mmagician
mmagician marked this pull request as ready for review September 4, 2026 15:15

@bobbinth bobbinth left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good! Thank you!

@bobbinth
bobbinth enabled auto-merge September 4, 2026 20:53
@bobbinth
bobbinth added this pull request to the merge queue Sep 4, 2026
Merged via the queue into next with commit 8195bba Sep 4, 2026
20 checks passed
@bobbinth
bobbinth deleted the mmagician-claude/pin-fee-to-native-asset branch September 4, 2026 21:05
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.

AuthMultisig: unbounded fee conversion lets approvers drain the vault via the fee note

3 participants