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:
@@ -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;
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user