```
  BIP: 451
  Layer: Applications
  Title: Dust UTXO Disposal Protocol
  Authors: bubb1es <bubb1es71@proton.me>
           haris <harismuzaffer@gmail.com>
  Status: Draft
  Type: Specification
  Assigned: 2026-04-28
  License: CC0-1.0
  Discussion: 2026-01-25: https://delvingbitcoin.org/t/disposing-of-dust-attack-utxos/2215
              2026-03-30: https://groups.google.com/g/bitcoindev/c/pr1z3_j8vTc
  Version: 0.1.0
```

## Abstract

This BIP specifies a standardized protocol for safely disposing of dust UTXOs by spending them to an OP_RETURN output with the entire value going to transaction fees. The protocol describes how wallet software should remove unwanted small-value UTXOs received in dust attacks without degrading user privacy. The specification includes transaction format requirements, signature conventions enabling third-party batching, and validation rules for compliant implementations.

## Motivation

### The Dust Attack Problem

Dust attacks, also known as forced address reuse attacks, are a well-documented privacy threat where attackers send small "dust" amounts of bitcoin to numerous addresses. When wallet software later consolidates these dust UTXOs with non-dust UTXOs, the attacker uses the [common-input-ownership heuristic](https://en.bitcoin.it/wiki/Privacy#Common-input-ownership_heuristic) to link previously unassociated addresses together and with future spending, reducing the privacy of users.

The common solution to this issue is to "lock" dust attack UTXOs and never spend them, but this creates its own problems:

- **UTXO Set Bloat**: Unspent dust permanently occupies space in the UTXO set that all full nodes must maintain.
- **Wallet Clutter**: Accumulated dust degrades wallet usability and complicates coin selection.
- **Accidental Consolidation**: Users may inadvertently spend dust during legitimate transactions, achieving the attacker's goal.
- **Lock Fragility**: Wallet software that "locks" dust UTXOs to prevent spending provides only temporary protection; wallet migrations, restores from seed phrases, software bugs, or inheritance scenarios can inadvertently unlock dust, exposing users to the original attack.

### Why OP_RETURN Disposal

Spending dust to an OP_RETURN output with the entire value going to fees provides several benefits:

- **No New UTXOs**: OP_RETURN outputs are provably unspendable and not stored in the UTXO set.
- **No Address Linking**: Without a change output, there is no new address to link.
- **Permanent Removal**: The dust UTXOs are removed from the user's wallet entirely.
- **Miner Compensation**: OP_RETURN outputs are small, providing higher transaction fee rates.
- **No Cost to Victims**: Dust attack UTXO values are used to pay for their own disposal.

### Why Standardization

A standardized protocol enables:

- **Wallet Anonymity**: Transactions with a standard format cannot be used to fingerprint the wallet software a user is running.
- **Third-Party Batching**: Multiple dust disposals can be combined into single transactions, reducing overall block space consumption.
- **Best Practice Codification**: Ensures implementations follow privacy-preserving best practices.
- **Easy Identification**: Chain analysis tools can use disposal transactions to help trace the sources of dust attacks.

## Specification

### Transaction Format

A compliant dust disposal transaction MUST satisfy all the following requirements:

#### Overall

1. The nLockTime MUST be set to block height 0.
2. The fee rate MUST be at least the minimum transaction relay fee rate (0.1 sat/vB at the time of writing).

#### Output

1. The transaction MUST have exactly one output.
2. The single output MUST be an OP_RETURN.
3. The OP_RETURN data MUST be the three-byte ASCII string "ash":  
   `0x6a 0x03 0x61 0x73 0x68` (OP_RETURN OP_PUSHBYTES_3 "ash")

#### Inputs

1. All inputs MUST set the nSequence to 0xFFFFFFFF (do not signal for BIP 125 RBF).
2. All inputs MUST use the signature hash type `ALL|ANYONECANPAY` (0x81).
3. For Taproot (P2TR) inputs using key-path spending, implementations MUST explicitly append the signature hash type byte `ALL|ANYONECANPAY` (0x81) to enable ANYONECANPAY semantics, as the default sighash for Taproot (SIGHASH_DEFAULT, which omits the byte) does not include ANYONECANPAY.
4. All inputs must be confirmed in the blockchain at least one block deep.

#### Transaction Size

The transaction base size MUST be at least 65 bytes to meet the current bitcoin network minimum relay size standardness rule. This should always be the case due to the required output OP_RETURN with value "ash"; see the "Output" section above.

#### Fees

1. The entire input value MUST go to fees (the single OP_RETURN output amount is zero).
2. The transaction fee rate MUST meet the bitcoin network minimum relay requirements (0.1 sat/vB for Bitcoin Core 28.3, 29.1, 30.0+).
3. The transaction fee rate MAY be higher based on the available dust UTXO amounts and transaction size.

### Dust Selection

Implementations MUST select UTXOs that are under a user-configurable maximum bitcoin amount.

Implementations SHOULD NOT select dust UTXOs for disposal if there are any unspent, non-dust UTXOs for the same address. This is especially important if:

1. No funds have previously been spent from the address.
2. The address type uses a hashed public key (e.g. P2PKH, P2WPKH).

### Address Consolidation Rules

Implementations consolidating dust UTXOs owned by a single user (i.e., not batching unrelated dust UTXOs):

- MUST NOT spend dust UTXOs that were sent to different addresses in the same transaction.
- MUST NOT broadcast dust disposal transactions at the same time for dust sent to different addresses.
- SHOULD spend dust UTXOs for dust sent to the same address in one transaction.
- SHOULD try to batch a dust input with unconfirmed disposal transactions found in the mempool, see the "Batching" section below.

### Batching

Multiple unconfirmed dust disposal transactions created by unrelated entities can be batched into a single replacement transaction using RBF (replace by fee). But the entity doing the batching must not risk compromising the privacy of the dust UTXO owners. The best practices for batching are:

1. Signed dust inputs MUST be collected from unconfirmed transactions found in nodes' mempools.
2. Inputs MUST NOT be received directly from other wallet users.
3. All inputs MUST be spent to the same single OP_RETURN `ash` output, see the "Output" section above.
4. The batch creator MUST add a new dust UTXO input, and the resulting replacement transaction MUST satisfy BIP 125 RBF rules:
   - The replacement transaction's absolute fee MUST be at least the sum of the absolute fees for all replaced transactions. In dust disposal transactions this is inherently satisfied because the batcher's new input contributes additional sats that all become fee.
   - The replacement transaction MUST pay an additional fee of at least the incremental relay fee rate (the current minimum rate is 0.1 sat/vB) multiplied by the replacement transaction's virtual size. Since all input sats become fee in a dust disposal transaction, this reduces to: the sum of the batcher's new dust input values MUST be at least the minimum rate (e.g. 0.1 sat/vB) multiplied by the replacement transaction's virtual size.
   - The replacement transaction's fee rate MUST exceed the fee rate of every transaction it replaces.
   - The replacement transaction MUST NOT cause the eviction of more than 100 transactions from the mempool.

5. Unconfirmed dust disposal transactions MUST be sorted in ascending order by fee rate before selecting which to batch. The batch creator MUST iterate through this sorted list and greedily include transactions until an RBF rule is not met. This deterministic ordering ensures all compliant implementations produce the same batch for the same mempool state, preventing implementation fingerprinting.

Batch dust disposal transactions must follow all other transaction construction requirements for non-batched dust disposal transactions.

This mempool-based approach preserves user privacy while enabling efficient batching:

1. If no unconfirmed dust disposal transactions exist in the mempool, broadcast a new dust disposal transaction to the network.
2. When one or more unrelated, unconfirmed dust disposal transactions are found, try to create a compliant batch transaction with them.
3. If no valid batch transaction can be created, fall-back to option 1.

### Security Considerations

#### Transaction Signing

- **Key Security**: Signing dust disposal transactions requires signing with the user's wallet private keys. This could be a risk for cold storage wallets where the key or keys needed to sign are not easily accessible.
- **Transaction Correctness**: Transaction signers must carefully review and verify that only dust UTXOs are spent and no other inputs are signed.

#### Privacy Preservation

- **Network surveillance**: Internet service providers and other internet monitors may be able to determine the nodes that initially broadcast a dust disposal transaction. If available the `sendrawtransaction -privatebroadcast` RPC feature should be used (e.g., available in Bitcoin Core 31.0+).
- **Timing Analysis**: Users should be aware that the timing of dust disposal transactions is publicly observable. Dust disposal transactions for different addresses should NOT be broadcast at the same time or on a predictable schedule.
- **Amount Analysis**: The specific dust amounts selected for dust disposal if outside the norm may be used to fingerprint the wallet creating the disposal transactions.

#### Public Key Exposure

- **Long term quantum attack**: Spending dust UTXOs for address types with a hashed public key reveals that public key. This would make non-dust funds locked by the same addresses vulnerable in a hypothetical future where cryptographically relevant quantum computers (CRQC) capable of long-exposure attacks against 256-bit ECDLP public keys exist.
- **Targeted dust**: An attacker may send dust UTXOs to a victim's wallet specifically to trick them into disposing of it and revealing the address's public key. This targeting could happen in anticipation of any future cryptographic attack that requires an exposed public key.

## Rationale

### Why "ash" OP_RETURN Data?

- **Minimal Size**: The "ash" string (5 bytes: OP_RETURN OP_PUSHBYTES_3 "ash") provides a standardized way to meet the minimum transaction size for dust disposal transactions with a single witness input (e.g., P2WPKH, P2WSH, P2TR).
- **Batching**: Using the same output script for all input types allows any disposal transactions to be batched (as long as they also meet the other batching and RBF rules).
- **Standardization**: Consistent transaction construction eliminates wallet fingerprinting.
- **Semantic Meaning**: The word "ash" metaphorically represents the result of "burning" the dust.

### Why Per-Address Transactions?

Consolidating dust from multiple addresses for the same wallet creates the same privacy harm that dust attacks attempt to achieve. By requiring implementations to create separate transactions per address (by default), the protocol ensures dust disposal doesn't harm privacy.

### Why 65-Byte Minimum?

Bitcoin relay policy enforces a minimum transaction base size of 65 bytes to prevent certain attack vectors. Compliant transactions must meet this threshold to be relayed by standard nodes.

### Why 0.1 sat/vB Minimum Fee Rate?

Dust disposal transactions must meet the minimum relay fee rate, which is currently 0.1 sat/vB (Bitcoin Core 28.3, 29.1, 30.0+). This allows dust UTXOs to be disposed of economically even when their value is small. Implementations targeting older node versions may need higher minimum fee rates. Dust disposal transactions should always pay at least the current standard minimum relay fee rate if it changes in the future.

### Why Sighash `ALL|ANYONECANPAY`?

The `ALL` sighash flag means that the signature commits to all outputs of the transaction. This means signed dust inputs can only be spent to the special OP_RETURN output of a dust disposal transaction.

The `ANYONECANPAY` sighash flag means that the signature only commits to the one input being signed. This means anyone can add additional inputs to the dust disposal transaction after signing. When batching dust UTXOs, we do not care which dust UTXOs are spent together as long as they do not associate addresses owned by the same entity.

Together these flags enable:

- **Batching**: A new dust input can be added to an unconfirmed dust disposal transaction found in the mempool and batched together via RBF.
- **User privacy**: Dust disposal transactions shared via the public mempool do not reveal user identity metadata.
- **Fee Bumping**: Additional inputs can be added by unrelated third parties to improve the fee rate.
- **Limited RBF**: By committing dust inputs to a single `OP_RETURN` output we restrict these inputs to only being spent with other disposal inputs. This limits the number of valid conflicting RBF transactions that can be created and relayed.

### Why nLockTime block height 0

- **User privacy**: Using the same nLockTime for all dust disposal transactions obscures when it was created.
- **Fee sniping**: The value of disposal transactions should be small enough that fee sniping is not a concern.
- **Fingerprinting**: Using the same nLockTime value for all dust disposal transactions prevents different implementations from being identified by this value.

### Why nSequence 0xFFFFFFFF

- **Fingerprinting**: Using the same nSequence value for all dust disposal inputs prevents different implementations from being identified by this value.
- **Best practice**: BIP 125 Opt-in Full Replace-by-Fee Signaling is not required (as of Bitcoin Core 28.0+). This is a common nSequence value when not encoding a relative timelock.

### Why only confirmed UTXOs

- **Double-spend protection**: Only disposing of confirmed UTXOs prevents the attacker from double spending them to prevent their disposal.
- **No urgency**: There is generally no urgency in disposing of dust attack UTXOs, they can be locked to prevent accidentally spending them before they are confirmed and safely disposed of.

## Backwards Compatibility

This BIP requires no changes to the Bitcoin consensus rules or peer-to-peer protocol. All transactions conforming to this specification are valid under existing consensus rules and can be relayed by nodes supporting:

- Sighash `ALL|ANYONECANPAY` (original Bitcoin feature)
- OP_RETURN outputs relay policy (Bitcoin Core 0.9.0+)
- RBF (Replace by Fee) BIP 125 (Bitcoin Core 0.12.0+)
- 0.1 sat/vB minimum relay fee (Bitcoin Core 28.3, 29.1, 30.0+)
- Private transaction broadcast (Bitcoin Core 31.0+)

Any nodes configured to require a relay fee rate above the standard minimum fee rate (currently 0.1 sat/vB) could slow, but not stop, the propagation of disposal transactions that use the lower fee rate.

## Reference Implementation

A reference implementation is available at: https://github.com/bubb1es71/ddust

The implementation provides:
- Command-line tool for creating dust disposal transactions
- Automatic dust detection based on a configurable amount threshold
- Transaction batching via RBF
- Support for P2PKH, P2SH, P2WPKH, P2WSH, and P2TR input descriptors
- Integration with Bitcoin Core (version 31.0+) via RPC for syncing and broadcasting transactions

## Test Cases

The test cases below can be used to verify a wallet disposes of dust UTXOs according to the specification in this BIP. 

### List dust

1. Create payment addresses for multiple address types, send dust and non-dust amounts to these addresses, verify that listing dust only returns UTXOs at or below the configured dust threshold (e.g. 1000 sats).
2. Create confirmed and unconfirmed dust UTXOs in the test wallet, verify listing dust only returns the confirmed dust UTXOs.

### Spending dust

All valid dust disposal transactions should be verified to be accepted into the bitcoind (Bitcoin Core 30.0+) mempool.

1. Spending a single witness (Bech32m/P2TR) dust UTXO must produce a dust disposal transaction with a single "ash" OP_RETURN output.
2. Spending multiple dust UTXOs for the same address produces a single "ash" OP_RETURN output regardless of script type.
3. Spending a single 2-of-2 P2SH multisig dust UTXO produces a single "ash" OP_RETURN output.
4. All dust UTXOs sent to the same address are disposed of in the same transaction.
5. Dust disposal transactions only include confirmed dust UTXOs.

#### Example dust disposal transaction sizes

|                     | P2PKH | P2SH (2-3) | P2WPKH | P2WSH (2-3) | P2TR  |
|---------------------|-------|------------|--------|-------------|-------|
| Overhead (B)        | 10    | 10         | 10     | 10          | 10    | 
| Input (B)           | 147   | 293        | 41     | 41          | 41    |
| OP_RETURN "ash" (B) | 14    | 14         | 14     | 14          | 14    |
| Base size (B)       | 171   | 317        | 65     | 65          | 65    |
| Witness data (B)    | 0     | 0          | 107    | 252         | 67    |
| Size (B)            | 171   | 317        | 172    | 317         | 132   |
| Weight (wu)         | 684   | 1268       | 369    | 514         | 329   |
| Virtual Size (vB)   | 171   | 317        | 92.25  | 128.50      | 82.25 | 

#### Example dust disposal transaction fee rates (sats/vB)

| Input Amount (sats) | P2PKH   | P2SH (2-3) | P2WPKH | P2WSH (2-3) | P2TR  |
|---------------------|---------|------------|--------|-------------|-------|
| 294                 | 1.72    | 0.93       | 3.19   | 2.29        | 3.57  |
| 300                 | 1.75    | 0.95       | 3.25   | 2.33        | 3.65  |
| 325                 | 1.90    | 1.03       | 3.52   | 2.53        | 3.95  |
| 330                 | 1.93    | 1.04       | 3.58   | 2.57        | 4.01  |

### Batching dust disposal txs via RBF

1. Adding a Bech32m dust input to an unconfirmed disposal transaction with a legacy dust input keeps the original single "ash" OP_RETURN output.
2. Adding a Bech32m dust input to an unconfirmed disposal transaction with a Bech32m dust input keeps the original single "ash" OP_RETURN output.
3. Adding a new dust input to an unconfirmed disposal transaction results in a new batch disposal transaction with a fee rate sufficient for RBF.
4. A new dust input that contributes an insufficient amount for RBF with an existing unconfirmed disposal transaction is not batched with it.

## Related work

* "dust-b-gone": https://github.com/petertodd/dust-b-gone
* "dusts":  https://github.com/bubb1es71/dusts

## Changelog

* **0.1.0** (2026-04-28):
    * Initial draft of the BIP.

## Copyright

This document is licensed under the Creative Commons CC0 1.0 Universal license.
