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

@@ -92,11 +92,13 @@ canonical enum lives in `packages/core` (see [Canonical enum](#canonical-enum)).
- **Allowed action(s):** None. These are skipped.
- **Rent / Essence rules:** No rent recovery and no Essence.
- **Example asset types:**
- Token-2022 accounts (in the MVP)
- Unknown token program
- Bad / missing metadata
- 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
builder must enforce **all** of these. MVP rules:
- [ ] Classic SPL only.
- [ ] Skip Token-2022 by default.
- [ ] Support classic SPL **and** Token-2022; gate Token-2022 on account+mint
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 compressed NFTs.
- [ ] 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:
1. **Scan** — fetch the token account: owner, ATA address, mint, token program,
raw/UI balance, decimals, metadata if available, token program type, and
frozen/delegated state if available.
2. **Token program check** — if not classic SPL (e.g. Token-2022, unknown
program), classify as `UNSUPPORTED`. Stop.
3. **Account integrity check** — if metadata is bad/missing, the account layout
is unsupported, or extension behavior is unhandled, classify as
raw/UI balance, decimals, metadata if available, token program type,
frozen/delegated state, and (Token-2022) the account **and mint** extension
list.
2. **Token program check** — classic SPL and Token-2022 are both supported. An
unknown/other token program ⇒ `UNSUPPORTED`. Stop.
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.
4. **Protected check**if the asset is an NFT, compressed NFT, LP token,
receipt token, staked token, major/known-valuable asset, SOL/WSOL special
case, suspicious token, frozen account, delegated account, or a high-value /
5. **Lock check**frozen or delegated accounts are skipped regardless of
balance: classify as `PROTECTED_SKIP`. Stop.
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.
5. **Empty check**if the balance is zero, classify as `EMPTY_CLOSE_ONLY`.
Stop.
6. **Route check** — evaluate a swap route. If a safe route exists and passes all
8. **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,
simulation passes), classify as `TRANSMUTABLE`. Stop.
7. **Fallback** — otherwise the account has a balance with no safe route but may
simulation passes), classify as `TRANSMUTABLE`. Stop. (No swap routing in MVP
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`.
At any step where the system cannot safely decide, it falls back to a