-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Define protocol-level handling of unwanted assets when accounts are reaped #11664
Description
RFC: https://forum.polkadot.network/t/polkadot-protocol-proposals-rfc-process/1421/31
Problem
Substrate-based chains support account reaping (e.g. via existential deposits).
At the same time, they also support permissionless multi-asset transfers (Assets, ForeignAssets, NFTs, etc.).
This combination creates an unresolved edge case:
What should happen to assets held by an account that is reaped, especially when those assets were not consented to by the account owner?
Currently:
- Any account can receive arbitrary assets
- An account can be reaped based solely on native balance
- There is no standardized protocol‑level rule for how non-native assets owned by that account should be resolved
This leads to ambiguity, potential griefing vectors, and inconsistent behavior across pallets.
Why this matters
1. Unwanted / spam assets are a real phenomenon
Accounts can receive:
- Dust assets
- Spam tokens
- Unwanted NFTs
- Non-transferable or non-burnable assets
The recipient neither opted into these assets nor has a safe or obvious way to dispose of them.
2. Reaping becomes underspecified
If an account is reaped:
- Should foreign assets block reaping?
- Should they be transferred?
- Burned?
- Left orphaned?
Today this is implicit, pallet-specific, or undefined.
3. Potential griefing vector
Without clear semantics, an attacker could:
- Send minimal assets to accounts
- Interfere with account lifecycle assumptions
- Create unexpected long‑lived state tied to dead accounts
4. Indexers, wallets, and tooling cannot rely on consistent behavior
Tooling is forced to:
- Guess what “account death” means
- Add chain‑specific heuristics
- Work around inconsistencies that should be protocol-defined
Observations from other ecosystems
Ethereum avoids this problem by:
- Never reaping accounts
- Treating untouched assets as inert
However, Substrate does reap accounts, so the protocol must explicitly decide what happens to all dependent state — including assets the user did not consent to receive.
Design Goal
Define deterministic, protocol-level semantics for handling assets owned by an account when that account is reaped, without requiring user interaction.
The solution should:
- Preserve permissionless transfers
- Avoid forcing users to interact with unwanted assets
- Be deterministic and auditable
- Be cheap and safe to execute
- Avoid pallet‑specific ad‑hoc behavior
Proposed Direction (conceptual)
Introduce a standardized “on account reaped” resolution step for all asset‑providing pallets.
High-level idea
When the runtime determines that an account should be reaped:
- The account is marked for removal
- All asset providers are invoked to resolve balances held by that account
- Resolution happens automatically and cannot fail
This mirrors how account lifecycle hooks are already centralized, but extends them to asset ownership.
Possible resolution strategies
This issue does not prescribe a single behavior, but suggests defining a small, explicit set of allowed strategies, for example:
-
Burn on reap
Remove the asset balance and reduce issuance (or mark as destroyed) -
Return to issuer / admin
Suitable for permissioned assets -
Transfer to a system sink
e.g. treasury or dust account -
Ignore (remove balance without supply change)
Effectively treating the asset as lost/inert
The key requirement is that one of these behaviors must be defined, rather than implicit or accidental.
Important non-goals
- ❌ Blocking inbound transfers
- ❌ Requiring user approval or interaction
- ❌ Making reaping fail because foreign assets exist
- ❌ Asset-specific hacks without shared semantics
Open questions
- Should “burn on reap” be the default for non-consensual assets?
- Should asset pallets be required to declare an on‑reap policy?
- How should legacy pallets be handled?
- Should native and non-native assets be treated differently?
Why this belongs in polkadot-sdk
This is not a UI concern and not a chain‑specific policy decision — it is a runtime‑level account lifecycle semantic.
Defining this at the SDK level would:
- Improve security and predictability
- Eliminate a class of griefing vectors
- Simplify pallet design
- Clarify Asset Hub and multi‑asset behavior
- Improve downstream tooling consistency
Summary
Today, Substrate defines when an account dies, but not what happens to assets that depend on it.
This issue proposes clarifying that boundary by defining explicit, deterministic behavior for unwanted or non-consensual assets at the moment of account reaping.