Skip to content

Reject transactions that spend a treasury UTXO without creating a new one#369

Merged
Ash-L2L merged 2 commits into
LayerTwo-Labs:masterfrom
1440000bytes:fix/treasury-spent-without-new-ctip
Jun 4, 2026
Merged

Reject transactions that spend a treasury UTXO without creating a new one#369
Ash-L2L merged 2 commits into
LayerTwo-Labs:masterfrom
1440000bytes:fix/treasury-spent-without-new-ctip

Conversation

@1440000bytes
Copy link
Copy Markdown
Contributor

@1440000bytes 1440000bytes commented Jun 4, 2026

Per BIP300 a transaction that spends a treasury UTXO as an input and creates no new treasury UTXO as an output is invalid.

https://github.com/LayerTwo-Labs/bip300_bip301_specifications/blob/master/bip300.md#validation-rules-specification

handle_m5_m6 builds ctip_spends (treasury inputs) but only consults it inside the loop over new_ctips (treasury outputs). A tx that spends a treasury UTXO and creates no new treasury output never enters that loop, so it returns Ok(None) and is ignored. OP_DRIVECHAIN is anyone-can-spend, so anyone could drain a sidechain's treasury this way.

This adds the missing check. Every spent treasury must have a corresponding new treasury output, otherwise the tx is invalid. Block-level rejection of the invalid tx is handled by #365 (which propagates non-fatal tx errors instead of
skipping them).

@Ash-L2L
Copy link
Copy Markdown
Collaborator

Ash-L2L commented Jun 4, 2026

Thanks! LGTM

@Ash-L2L Ash-L2L merged commit f9e21fd into LayerTwo-Labs:master Jun 4, 2026
17 checks passed
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.

2 participants