feat(fee+burn+essence): 5% transparent fee, burn→close, Essence ledger + dashboard

Monetization (design Rev 4, §3.1) — transparent in-tx fee, non-custodial:
- @pyre/core: computeFeeBreakdown (single source of truth, BigInt) + FeeBreakdown
  threaded through close/burn previews; fee tests.
- @pyre/config: PYRE_TREASURY_WALLET / PYRE_FEE_BPS (500) / swap fee / max contribution.
- @pyre/solana: close-empty + burn→close now append ONE System transfer of exactly
  the disclosed fee to the treasury; rent/authority/feePayer pinned to wallet.
  buildBurnTx re-validates EVERY account on-chain and value-gates via the classifier
  (classic SPL + Token-2022) — never burns protected/valuable/NFT/unsupported;
  ignores client amount (burns real balance); whole-build rejection.
- @pyre/api: close-empty/burn endpoints carry the fee + bounded optional contribution;
  /api/receipt persists (cleanup_receipts) and records the on-chain treasury fee as
  Essence; GET /api/essence; startup migrate(). Best-effort DB (never fails receipts).
- @pyre/db: Postgres Essence ledger (rounds, cleanup_receipts, essence_contributions),
  idempotent migrations, parameterized + u64-safe.
- @pyre/web: fee preview ("reclaim · feeds the PYRE · you net" + treasury) + optional
  "feed more" slider; burn flow w/ destructive confirm; decode+match verifies the fee
  transfer (treasury + exact lamports) before signing; public "🔥 fed the PYRE" panel.

Built by agents (2 waves) + 2 audits. Security audit found a HIGH — buildBurnTx
didn't value-gate CLASSIC spl tokens (a direct API caller could burn USDC/an NFT);
FIXED (classify classic accounts too) + 2 regression tests. Integration: SHIP.
typecheck 8/8, core 91, solana 30, web build green. Live: burn preview on the dust
token shows 5% → treasury; non-empty/non-owned/valuable rejected. Nightly DB backup
cron enabled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-31 06:11:00 +00:00
parent f9c471ef71
commit b98b904896
22 changed files with 3115 additions and 182 deletions

View File

@@ -18,6 +18,14 @@
> via the **Jupiter** aggregator (§6.1) — PYRE builds no swap math and runs no
> pump.fun engine. Essence is **model 1**: net SOL stays in the user's wallet and
> is recorded as an opt-in off-chain tally; **no custody** until the v1.0 program.
>
> **Revision note — Rev 4 (2026-05-31):** Monetization locked. Recovered rent
> returns to the user **minus a transparent 5% protocol fee** (taken in the signed
> tx, shown before signing), plus an **optional user-chosen extra contribution**.
> Fees = Essence that seeds Spawn launches + the contributor claim pool — this is
> the value loop that makes PYRE more than a burn service. Swap proceeds always go
> to the user (only a ~1% swap fee). See §3.1. Fee treasury (MVP):
> `122CNV5ZLu6fqZFpEMUdUSQwDv2zs23pkYQhkNtSQk5k` (swap for a multisig before scale).
---
@@ -66,21 +74,52 @@ entertainment.
## 3. Core Trust Rule
> **Recovered ATA rent returns to the user by default.**
> **Recovered ATA rent returns to the user, minus one transparent, previewed
> protocol fee.** (Rev 4 — amends the original "rent is never taxed" stance to a
> sustainable, disclosed fee; see §3.1.)
Rent must not be silently taxed, redirected, pooled, or used as Essence unless a
future version creates an explicit opt-in donation mode.
Rent must never be **silently** taxed, redirected, or pooled. The ONLY deduction
is a single, clearly-disclosed protocol fee shown in the transaction the user
signs; everything else stays with the user.
For MVP:
- recovered rent goes to the user,
- recovered rent goes to the user **minus the disclosed protocol fee** (§3.1),
- the fee is shown before signing (gross reclaimed · fee · net to you) and is an
instruction **inside the user-signed tx** — never a hidden/after-the-fact charge,
- burned junk does not count as Essence,
- swapped scraps may become Essence **only if the user explicitly approves**,
- optional SOL contribution must be separate and explicit,
- swapped scraps: proceeds go to the **user** (PYRE never keeps swap output); only
the disclosed swap fee is taken,
- any **optional extra contribution** ("feed the PYRE more") must be explicit and
user-chosen, on top of the base fee — never defaulted on,
- all actions require wallet approval,
- **PYRE never has custody of private keys.**
- **PYRE never has custody of private keys** (the treasury receives only fee SOL;
it never holds user funds).
> **PYRE returns your rent. The scraps feed the fire.**
> **PYRE returns your rent — minus a small fee that feeds the fire.**
### 3.1 Protocol fee & Essence (the value loop)
PYRE is sustained — and the PYRE is fed — by a small, transparent fee on what it
recovers (industry-standard for Solana cleaners; e.g. Sol Incinerator ~2%). PYRE's
fee is deliberately in the fair band:
| Action | Fee | Who gets the rest |
|---|---|---|
| Close empty ATA / burn-then-close (reclaimed rent) | **5%** | 95% → user |
| NFT / Token-2022 (larger rent) burn-then-close | **5%** | 95% → user |
| Swap to SOL (transmute) | **~1%** | 100% of swap proceeds → user |
| Optional "feed the PYRE more" | user-chosen extra % | — |
- The fee is taken as an explicit transfer instruction to the **PYRE treasury** in
the same transaction the user signs, and is shown in the preview. Non-custodial:
the user signs; PYRE holds no keys; the treasury receives only fee SOL.
- Collected fees (+ opt-in contributions) are **Essence** — they pool to seed
**Spawn** launches and the contributor **claim** pool (§9, §18). This is what
makes PYRE more than a burn tool: clean = the hook, the fee = the fuel,
Spawn+claim+rounds = the differentiation.
- Trust is the moat: always display net SOL + the exact fee before signing; never
inject undisclosed instructions; never keep swap proceeds.
---