docs: bring Token-2022 (Token Extensions) into MVP scope (extension-gated)

Most new tokens — incl. all Pump.fun launches — are Token-2022, so cleaning
only classic SPL misses the majority of real dust. PYRE now supports Token-2022
conservatively, gating on account+mint extensions:
- skip: confidential transfer, withheld transfer fees, frozen/default-frozen,
  and any unrecognized extension (UNSUPPORTED). "Unknown means skip" now covers
  unknown program OR unknown/unsafe extension.
- cleanable but flagged: transfer-hook & permanent-delegate (burn/close don't
  fire a hook; you may always burn/close your own account); non-transferable is
  burnable.
- rent reclaim = account's live lamports (Token-2022 size varies); CloseAccount
  as a top-level instruction (CPI-Guard safe).

Updated PYRE_MVP_DESIGN.md (§5/§6/§7 + new §7.1 policy table + §8/§16),
TOKEN_CLASSIFICATION.md (categories, safety checklist, decision flow), SECURITY.md.
Researched against Solana docs + Neodyme review. Classifier CODE still skips all
Token-2022 (safe subset) until the extension-aware impl lands next.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-31 03:56:27 +00:00
parent d159ad5196
commit ae33b6d794
3 changed files with 126 additions and 33 deletions

View File

@@ -5,6 +5,13 @@
**Tagline:** *Burn the dead. Feed the PYRE. Claim the Spawn.* **Tagline:** *Burn the dead. Feed the PYRE. Claim the Spawn.*
> **Revision note — Rev 2 (2026-05-31):** Token-2022 (Token Extensions) is now
> **in MVP scope**. Most new tokens — including everything launched on Pump.fun —
> are Token-2022, so cleaning only classic SPL would miss the majority of real
> dust. PYRE supports Token-2022 conservatively, gating on account/mint
> **extensions** (see §7.1). The original brief's "skip Token-2022" stance is
> superseded by this revision.
--- ---
## 1. Project Summary ## 1. Project Summary
@@ -131,9 +138,16 @@ believable.
selected junk to zero; close emptied accounts after burn; show selected junk to zero; close emptied accounts after burn; show
skipped/protected tokens; export/share receipt image. skipped/protected tokens; export/share receipt image.
**v0.1 token-program support:** classic **SPL Token** AND **Token-2022** token
accounts are scanned, classified, closed, and burned — Token-2022 only when its
account/mint extensions are safe to act on (see §7.1). Token-2022 accounts with
unhandled extensions (confidential transfer, withheld transfer fees, unknown
extensions) and all frozen accounts are skipped.
**v0.1 must NOT include:** automatic Pump.fun launch, user-contributed Essence **v0.1 must NOT include:** automatic Pump.fun launch, user-contributed Essence
vault, custom PYRE Solana program, Token-2022 support, NFT handling, automatic vault, custom PYRE Solana program, NFT handling, automatic valuable-token
valuable-token sacrifice, custodial signing, background wallet automation. sacrifice, custodial signing, background wallet automation, on-chain swap routing
(TRANSMUTABLE), or any Token-2022 confidential-transfer / fee-harvest flows.
### MVP v0.2 — Prometheus Meta Mixer ### MVP v0.2 — Prometheus Meta Mixer
AI generation from burned/cleaned token context. AI generation from burned/cleaned token context.
@@ -187,11 +201,21 @@ Token accounts are classified into conservative categories.
USDC/USDT/major assets, valuable meme tokens, NFTs, LP tokens, receipt tokens, USDC/USDT/major assets, valuable meme tokens, NFTs, LP tokens, receipt tokens,
staked tokens, suspicious tokens, frozen accounts, delegated accounts, staked tokens, suspicious tokens, frozen accounts, delegated accounts,
high-value balances. high-value balances.
- **UNSUPPORTED** — system cannot safely reason about it. Examples: Token-2022 in - **UNSUPPORTED** — system cannot safely reason about it. Examples: unknown token
MVP, unknown token program, bad metadata, unsupported account layout, accounts program, bad metadata, unsupported account layout, and **Token-2022 accounts or
with extension behavior not yet handled. mints carrying extensions PYRE does not yet safely handle** — confidential
transfer, accounts with withheld transfer fees, or any unrecognized extension
(see §7.1).
> **Default rule: Unknown means skip.** Token-2022 accounts with only benign/no extensions are classified exactly like
classic SPL (EMPTY_CLOSE_ONLY / INCINERATE_ONLY / PROTECTED_SKIP), using the
Token-2022 program for the close/burn instructions. Transfer-hook and
permanent-delegate mints are still cleanable (burn/close don't trigger a transfer
hook, and you may always burn/close your own account) but are **flagged** and
excluded from any future swap.
> **Default rule: Unknown means skip** — unknown token program *or* unknown/unsafe
> Token-2022 extension.
--- ---
@@ -199,8 +223,14 @@ Token accounts are classified into conservative categories.
The classifier must be conservative. MVP rules: The classifier must be conservative. MVP rules:
- Classic SPL only. - Support classic **SPL Token** and **Token-2022**; gate Token-2022 on its
- Skip Token-2022 by default. account *and* mint extensions per §7.1 (skip confidential transfer, withheld
transfer fees, and any unknown extension).
- Use the correct token program per account for every instruction (classic vs
Token-2022); perform `CloseAccount` as a **top-level** instruction (CPI-Guard
safe).
- Reclaimable rent is the account's **live lamport balance** (Token-2022 rent
varies with extensions) — never a fixed constant.
- Skip NFTs. - Skip NFTs.
- Skip compressed NFTs. - Skip compressed NFTs.
- Skip LP tokens. - Skip LP tokens.
@@ -216,14 +246,57 @@ The classifier must be conservative. MVP rules:
> The system should never say *"This token is safe."* > The system should never say *"This token is safe."*
> It should say *"This token appears eligible based on current checks."* > It should say *"This token appears eligible based on current checks."*
### 7.1 Token-2022 (Token Extensions) Support
Token-2022 accounts and mints can carry **extensions** that change what is safe
to close, burn, or swap. The scanner reads extensions from `jsonParsed` RPC data
on **both** the token account and its mint (transfer hook, permanent delegate,
and confidential-transfer config live on the *mint*). Closing requires a
zero-balance, non-frozen account; burning is owner-authorized and does **not**
invoke a transfer hook.
Program IDs:
- Classic SPL Token — `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`
- Token-2022 — `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb`
Conservative per-extension policy (default for any **unknown extension → skip**):
| Extension | close-empty | burn-then-close | swap (future) |
|---|---|---|---|
| None / Immutable-Owner / Memo / Metadata / Interest-Bearing | allow | allow | allow |
| Non-Transferable (soulbound) | allow | allow (owner may burn) | block |
| Transfer Hook (mint) | allow (no hook on close) | allow (no hook on burn) | **skip** + flag |
| Permanent Delegate (mint) | allow | allow + **scam flag** | **skip** + flag |
| Transfer Fee | allow only if **no** withheld balance | allow (harvest withheld before close) | allow, fee disclosed |
| Default-Frozen / account `state == frozen` | **skip** | **skip** | **skip** |
| Confidential Transfer | **skip** (needs drain + ZK-proof close) | **skip** | **skip** |
| CPI Guard | allow (close as top-level ix) | allow | review |
| Unknown / unrecognized | **skip** | **skip** | **skip** |
Per-account preflight (server-side, never trust the client):
1. Read `info.state` — skip if `frozen`.
2. Read `tokenAmount.amount``0` ⇒ close path; non-zero ⇒ burn-then-close.
3. Read the token-account extensions — `confidentialTransferAccount` ⇒ skip;
`transferFeeAmount.withheldAmount > 0` ⇒ skip (harvest-first is out of MVP scope).
4. Read the **mint** extensions — transfer hook / permanent delegate ⇒ flag
(cleanable, but warn and exclude from swap).
5. Any unrecognized extension ⇒ UNSUPPORTED.
6. Reclaim = the account's live lamports; sign with the account owner / its
`CloseAuthority`.
Out of MVP scope (later phases): confidential-transfer close (drain + ZK proof),
transfer-fee withheld-balance harvesting, and swapping hook/permanent-delegate
tokens.
--- ---
## 8. Burner Transaction Flow ## 8. Burner Transaction Flow
1. **Wallet Connect** — user connects via Solana Wallet Adapter. 1. **Wallet Connect** — user connects via Solana Wallet Adapter.
2. **Account Scan** — query token accounts. For each: owner, ATA address, mint, 2. **Account Scan** — query token accounts. For each: owner, ATA address, mint,
token program, balance, decimals, rent estimate, metadata if available, token token program, balance, decimals, rent estimate (live lamports), metadata if
program type, frozen/delegated state if available. available, token program type, frozen/delegated state, and — for Token-2022 —
the account **and mint** extension list (§7.1).
3. **Classification** — each account classified; UI groups into: closeable empty 3. **Classification** — each account classified; UI groups into: closeable empty
accounts, burnable junk, potentially transmutable scraps, protected/skipped, accounts, burnable junk, potentially transmutable scraps, protected/skipped,
unsupported. unsupported.
@@ -445,9 +518,12 @@ spawn_records: id, generation_id, spawn_name, ticker, mint, metadata_ur
Never auto-execute without user signing. Always show transaction preview. Decode Never auto-execute without user signing. Always show transaction preview. Decode
transaction before signing. Match decoded transaction against preview. transaction before signing. Match decoded transaction against preview.
**Token Safety:** Unknown assets default to skip. Token-2022 default skip for **Token Safety:** Unknown assets default to skip — unknown token program *or*
MVP. NFTs default skip. Valuable assets default skip. User must manually select unknown/unsafe Token-2022 extension (§7.1). Token-2022 is supported only when its
anything risky. High-value actions require stronger confirmation. account/mint extensions are safe to act on; confidential-transfer, withheld-fee,
and frozen accounts are skipped. NFTs default skip. Valuable assets default skip.
User must manually select anything risky. High-value actions require stronger
confirmation.
**Backend Security:** Rate-limit scan endpoints. Validate wallet pubkeys. **Backend Security:** Rate-limit scan endpoints. Validate wallet pubkeys.
Validate token account ownership. Do not trust client-submitted classifications; Validate token account ownership. Do not trust client-submitted classifications;

View File

@@ -46,8 +46,12 @@ For the MVP:
## Token safety ## Token safety
- Unknown assets default to **skip**. - Unknown assets default to **skip** — unknown token program *or* unknown/unsafe
- Token-2022 defaults to **skip** for the MVP. Token-2022 extension.
- Token-2022 is **supported** with conservative extension gating (design doc
§7.1): confidential-transfer, withheld-transfer-fee, frozen, and any
unrecognized-extension accounts are **skipped**; transfer-hook /
permanent-delegate mints are cleanable but **flagged**.
- NFTs default to **skip**. - NFTs default to **skip**.
- Valuable assets default to **skip**. - Valuable assets default to **skip**.
- The user must **manually select** anything risky. - The user must **manually select** anything risky.

View File

@@ -92,11 +92,13 @@ canonical enum lives in `packages/core` (see [Canonical enum](#canonical-enum)).
- **Allowed action(s):** None. These are skipped. - **Allowed action(s):** None. These are skipped.
- **Rent / Essence rules:** No rent recovery and no Essence. - **Rent / Essence rules:** No rent recovery and no Essence.
- **Example asset types:** - **Example asset types:**
- Token-2022 accounts (in the MVP)
- Unknown token program - Unknown token program
- Bad / missing metadata - Bad / missing metadata
- Unsupported account layout - Unsupported account layout
- Accounts with extension behavior not yet handled - **Token-2022 accounts/mints with extensions not yet safely handled** —
confidential transfer, withheld transfer fees, or any unrecognized extension
(see design doc §7.1). Token-2022 with benign/no extensions is classified
like classic SPL.
--- ---
@@ -105,8 +107,11 @@ canonical enum lives in `packages/core` (see [Canonical enum](#canonical-enum)).
Reproduced from design doc §7 as a checklist. The classifier and any action Reproduced from design doc §7 as a checklist. The classifier and any action
builder must enforce **all** of these. MVP rules: builder must enforce **all** of these. MVP rules:
- [ ] Classic SPL only. - [ ] Support classic SPL **and** Token-2022; gate Token-2022 on account+mint
- [ ] Skip Token-2022 by default. extensions per design doc §7.1 (skip confidential transfer, withheld
transfer fees, frozen, and any unknown extension). Use the correct token
program per account; `CloseAccount` as a top-level instruction.
- [ ] Reclaimable rent = the account's live lamports (not a constant).
- [ ] Skip NFTs. - [ ] Skip NFTs.
- [ ] Skip compressed NFTs. - [ ] Skip compressed NFTs.
- [ ] Skip LP tokens. - [ ] Skip LP tokens.
@@ -138,23 +143,31 @@ current automated checks, not a guarantee about the asset.
How a single account flows from scan to a final category: How a single account flows from scan to a final category:
1. **Scan** — fetch the token account: owner, ATA address, mint, token program, 1. **Scan** — fetch the token account: owner, ATA address, mint, token program,
raw/UI balance, decimals, metadata if available, token program type, and raw/UI balance, decimals, metadata if available, token program type,
frozen/delegated state if available. frozen/delegated state, and (Token-2022) the account **and mint** extension
2. **Token program check** — if not classic SPL (e.g. Token-2022, unknown list.
program), classify as `UNSUPPORTED`. Stop. 2. **Token program check** — classic SPL and Token-2022 are both supported. An
3. **Account integrity check** — if metadata is bad/missing, the account layout unknown/other token program ⇒ `UNSUPPORTED`. Stop.
is unsupported, or extension behavior is unhandled, classify as 3. **Extension check (Token-2022)** — if the account/mint carries an extension
PYRE does not safely handle (confidential transfer, withheld transfer fees, or
any unrecognized extension), classify as `UNSUPPORTED`. Stop. Transfer-hook /
permanent-delegate mints continue but are flagged (see design doc §7.1).
4. **Account integrity check** — bad/missing metadata or unsupported layout ⇒
`UNSUPPORTED`. Stop. `UNSUPPORTED`. Stop.
4. **Protected check**if the asset is an NFT, compressed NFT, LP token, 5. **Lock check**frozen or delegated accounts are skipped regardless of
receipt token, staked token, major/known-valuable asset, SOL/WSOL special balance: classify as `PROTECTED_SKIP`. Stop.
case, suspicious token, frozen account, delegated account, or a high-value / 6. **Empty check** — if the balance is zero (and classic-SPL/Token-2022 with safe
extensions, not frozen/delegated), classify as `EMPTY_CLOSE_ONLY`. Stop.
(Empty accounts hold no value, so they close regardless of mint identity.)
7. **Protected check** — for a NON-empty balance: if the asset is an NFT,
compressed NFT, LP token, receipt token, staked token, major/known-valuable
asset, SOL/WSOL special case, suspicious token, or a high-value /
over-threshold balance, classify as `PROTECTED_SKIP`. Stop. over-threshold balance, classify as `PROTECTED_SKIP`. Stop.
5. **Empty check**if the balance is zero, classify as `EMPTY_CLOSE_ONLY`. 8. **Route check**evaluate a swap route. If a safe route exists and passes all
Stop.
6. **Route check** — evaluate a swap route. If a safe route exists and passes all
risk checks (no high price impact, no stale quote, no weird liquidity path, risk checks (no high price impact, no stale quote, no weird liquidity path,
simulation passes), classify as `TRANSMUTABLE`. Stop. simulation passes), classify as `TRANSMUTABLE`. Stop. (No swap routing in MVP
7. **Fallback** — otherwise the account has a balance with no safe route but may v0.1, so this never fires yet.)
9. **Fallback** — otherwise the account has a balance with no safe route but may
be burnable junk: classify as `INCINERATE_ONLY`. be burnable junk: classify as `INCINERATE_ONLY`.
At any step where the system cannot safely decide, it falls back to a At any step where the system cannot safely decide, it falls back to a