Skip to content

Instantly share code, notes, and snippets.

@staccDOTsol
Last active August 11, 2026 22:18
Show Gist options
  • Select an option

  • Save staccDOTsol/a9e18a690841231048e5329d9e22ec79 to your computer and use it in GitHub Desktop.

Select an option

Save staccDOTsol/a9e18a690841231048e5329d9e22ec79 to your computer and use it in GitHub Desktop.
Self-Feeding Snakes — a whitepaper about ouroboroi, written by someone who deployed them

Self-Feeding Snakes

A whitepaper about ouroboroi, written by someone who deployed them


Most protocol papers describe a machine that would work if people showed up. This one describes machines that are already running, and is honest about which of them are currently spinning in an empty room.

Every number here was measured. Where a mechanism is unproven I say so, in the same sentence, in the same font.


0. The one idea

A snake that eats its own tail gets smaller. That is usually a metaphor for failure. Here it is the product.

If a token's supply falls while its reserves do not, every remaining unit is worth more. No emission. No counterparty. No promise. Just fewer claims on the same pile. The trick is to make the shrinking automatic, permissionless, and impossible to switch off — and then to arrange the rest of the stack so that ordinary activity feeds it.

That is the whole paper. The rest is plumbing and receipts.


1. The wrapper — FrSERTNCPvTtaDS9AvQp9u1nYGzXDb3kC9MdL8Xxn2NE

Upstream spl-token-wrap is strictly 1:1: escrow balance always equals wrapped supply. A pure format shim, unable to express reserves growing.

The fork makes the wrapped mint a share of a pool instead:

wrap:    shares = assets × supply / reserves
unwrap:  assets = shares × reserves / supply

Reserves are read before the deposit lands. Pricing against post-transfer reserves values a depositor's own money as already pooled and mints them too few. The mirror rule applies on exit: reserves and supply are read before the burn, or the redeemer inflates their own payout.

Both directions round down, toward the pool. Rounding the other way is the classic ERC-4626 drain — deposit/withdraw cycles each skimming one unit, funded by everyone else. MINIMUM_LIQUIDITY = 1000 shares are burned into the first deposit and never redeemable, which kills the empty-vault inflation attack where the first depositor donates straight to the escrow and rounds everyone after them to zero. Uniswap V2 uses the same defence for the same reason.

Written in Pinocchio: no_std, no allocator, ~29.6 KB.

1.1 The snake

Token-2022's TransferFee extension withholds a fee on every transfer — in the recipient's account, deliberately, so one fee account never becomes a write-lock bottleneck. The cost is that collecting requires visiting holders. Hence a crank:

  1. harvest_withheld_tokens_to_mint — recipients → mint. Permissionless.
  2. withdraw_withheld_tokens_from_mint — mint → scratch. Authority-gated, and the authority is a PDA. This is the load-bearing choice: a keypair here means yield stalls whenever its holder is offline. A PDA lets the program sign, so the cycle is permissionless end to end.
  3. Split — half to treasury, half burned.

Measured, full cycle, mainnet:

reserves   100000  →  100000     (UNCHANGED — not new deposits)
supply      99000  →   98500     (fees burned)
NAV     1.01010101 → 1.01522843

Reserves did not move. The gain was not a subsidy and not a deposit. There are simply fewer claims on the same pile.

One detail nobody mentions in these papers: the treasury's own share is taxed on the way out too. 500 withheld arrived as 475. The dev cut pays the transfer fee like everybody else.

1.2 A vulnerability, and the correction

For one afternoon, crank_fees accepted a caller-supplied treasury account with no validation. Anyone cranking could name their own account and receive half of every harvested fee, with the program's own PDA signing the transfer.

Worse, the source comment claimed the opposite: "Neither half is payable to the caller, which is what keeps this safe to leave open to anyone." That was false, and it was written by the same hand that shipped it.

It is now bound by reading the treasury token account's owner field against a fixed constant. Pinocchio ships no PDA derivation at all — not find_program_address, not even create_program_address — so the check is a field read, not a syscall.

This is in the paper because a paper that only lists what went right is marketing.

1.3 Discovery

The wrapped mint is a caller-generated keypair, not a PDA of the underlying, so you cannot derive a market from an asset. A backpointer PDA at ["backpointer", wrapped_mint] records the pair — seed and first 32 bytes byte-identical to upstream, extra fields appended. 136 bytes, so the whole registry is one call:

getProgramAccounts(FrSERTNC…, filters: [{ dataSize: 136 }])

Registration is permissionless and idempotent; re-registering a different pair is rejected rather than silently repointing a live market.

Known limit: the record stores the unwrapped mint, but the wrapped mint is the PDA seed and is therefore not recoverable from the account. Full indexer-free discovery needs a wrapped_mint field and a length bump.


2. The floor — why a vault beats a buyback

A buyback is a promise to be nice with revenue. It can be raised, cut, or quietly ended. There is no reserve behind it, so it cannot define anyone's downside, and the first person out of the door still gets the best price. The bank-run equilibrium survives.

A vault-backed redemption floor removes it, because the exit price is defined before entry. First out and last out redeem against the same reserves / supply. There is no advantage to panicking.

This was proposed in a launchpad's team chat on 25 April 2024 — "people can back out for o.g. value at any time" — and never shipped there. It is the

The floor protects value. It does not guarantee profit.


3. The launchpad snake — oddballer.fun

This is the loudest one, and the one you can verify hardest, so it gets the receipts rather than the adjectives.

A protected-curve token launchpad on Sushi V4. Your worst case is printed on the page before you buy and enforced on chain: sells always redeem at NAV, and the floor only ever rises. At the time of writing the live flagship shows a maximum drawdown of -24.78%, stated up front, as a number rather than a vibe. That is not a risk disclosure bolted onto a casino. It is the product.

3.1 Three snakes eating at once

Every buy burns the platform token. 0.1% of every buy, on every coin, buys ODDBALLER and sends it to 0xdEaD. 107.2M burned so far. This is not a treasury choosing to be supportive — it is a permanent bid funded by activity itself, and there is no switch to turn it off or quietly reduce it.

Every buy pays 3,666 strangers. A fee-share NFT takes 0.1% of every buy across the whole platform, plus half of every mint that happens after yours, plus royalties. Share weight is set by mint tier — initiate 1×, adept 2×, magus 5×, archmage 10×, ascendant 20× — and read from the chain, not from a metadata file. Live: 119 minted, 588 shares outstanding, 0.2943 ETH paid out.

Anyone can turn the crank. Fees accumulate in the hook until somebody presses a button. That somebody pays the gas; every holder gets the credit. The machine does not require its operator to be awake, employed, or interested.

3.2 The part that is enforced, not promised

feePayeeB() on the hook returns 0x72c70189B5E0BB7d7ba1b830c3D152b0EE10992A — which is the fee-share NFT contract itself. The split between the deployer and the holders is not policy, not a multisig convention, and not a roadmap item. It is the return value of a getter. Query it.

owner() returns the deployer, and the deployer's fees accrue into the same creatorFees(address) mapping as everyone else's. There is no privileged withdrawal path. The dev claims exactly the way a creator claims.

3.3 Receipts

hook          0x028aA2A670416dFaBD5676aa967b0FE68742D91E
PoolManager   0x81d732702f87d2d652ae79e9f52bf44928eca210
fee-share NFT 0x72c70189B5E0BB7d7ba1b830c3D152b0EE10992A   (== feePayeeB())
ODDBALLER     0x923eb7BD5B84a1a114CB57212cE2F2e87AE60E2A

Pull this transaction and decode it yourself:

0xaf6a4ea1bf87b6e52f048261194e8de36e6e94dfe176194ae95822210d7544ee
  logs[3]  the hook
  logs[4]  PoolManager
  topics[0] Swap(...)   against poolId 0x5f4d4271…

That poolId is the exact one curveState() reports for the main curve. It was derived independently from the PoolKey — currency0 ETH, currency1 ODDBALLER, hooks the hook, fee 0 — and matched byte-for-byte.

3.4 What is not true yet

Being live on Sushi V4 and being routed to are different claims, and only the first one is currently proven.

Decoded receipts show one wallet's swaps multi-hopping through two separate V3 pools at fee tier 10000 and never touching the curve at all. So the honest version is: routing is inconsistent across tools, not "Sushi finds the curve". Every buy that did reach the curve did exactly what buying on the site would have done — just with more fee and gas overhead.

Fixing routing is the open problem. It is a distribution problem, not a mechanism problem, and pretending otherwise would be the sort of thing this paper exists to avoid.

4. The settlement snake — x402.accrue.fund

x402 is HTTP 402 put to work: a server quotes a price, the client pays inline, the request completes. No account, no invoice, no human.

An agent's balance between payments is dead money everywhere else. A deflationary wrapper keeps compounding while it sits, because the yield is supply reduction and supply reduction does not care that the token is idle.

  • Solana settles natively — no EIP-3009 equivalent needed. The facilitator sponsors the fee, verifies the payer signed and that exactly one token instruction is present.
  • Fee-on-transfer is quoted GROSS, so the payee receives the exact net. Naive flows break here: verifying delivered ≥ maxAmountRequired after a service grosses up is unsatisfiable at every amount.
  • The facilitator crawls the ecosystem rather than waiting for anyone to register. No developer was ever going to find a site and press "submit".

5. The validator snake — stacsol.app

Every Solana validator burns a fixed vote fee: 5,000 lamports × ~410,000 votes ≈ 2.05 SOL per epoch. Below ~5k stake that exceeds the inflation reward, so small validators run at a loss by design and the network centralises.

Patch: batch up to 31 votable banks into one TowerSync (the tower already accumulates the lockouts). Opt-in; N=1 is bit-for-bit identical to today.

Live on mainnet on a 2,341.72 SOL single-validator LST since 27 May 2026: 94.6% vote-fee reduction, 2.05 → 0.11 SOL/epoch, vote credits healthy.

The snake: cheaper validation → viable small validators → more decentralisation → a chain worth building the rest of this on.


6. How the snakes feed each other

        wrap  ──►  transfer fee  ──►  crank  ──►  burn  ──►  NAV ▲
          ▲                                                    │
          │                                                    ▼
     agents hold  ◄──  x402 settles  ◄──  idle float earns  ◄──┘

     launchpad buy ──► 0.1% ──► buy+burn platform token ──► permanent bid
                    └──► NFT fee share ──► 3,666 holders aligned with volume

None of these require a token emission, a governance vote, or anyone's continued goodwill. Each is a program. That is the only trust surface.


7. What is NOT true yet

A section every paper should have.

  • Yield is volume-driven, not calendar-driven. Accrual tracks transfers, not time. A quiet week earns exactly zero. The best-measured window on the EVM sibling was 58.71% simple / 78.12% compound over 21.24 days — real, but 4 of 6 sampled intervals were zero. Any APY here is a record of what happened, annualised. Never a rate you are owed.
  • The naive 7,482,703% that an ERC-4626 seeding artefact produces is an artefact. It is quoted here only so nobody quotes it at you.
  • Capped downside ≠ guaranteed profit.
  • Unaudited. One author, no external review. On-chain and readable, which is worth more than an audit badge and less than an audit.
  • Routing is inconsistent across aggregators, as above.
  • Several markets have zero supply. NAV is undefined until a genesis wrap.

8. Addresses

FrSERTNCPvTtaDS9AvQp9u1nYGzXDb3kC9MdL8Xxn2NE   wrapper program (Solana mainnet)
0x028aA2A670416dFaBD5676aa967b0FE68742D91E     curve hook (Robinhood Chain)
0x72c70189B5E0BB7d7ba1b830c3D152b0EE10992A     fee-share NFT / feePayeeB
0x923eb7BD5B84a1a114CB57212cE2F2e87AE60E2A     ODDBALLER
fragged.app          the venue — wrap, unwrap, create, crank
oddballer.fun        the launchpad with a floor
x402.accrue.fund     the facilitator
accrue.fund          the yield side
stacsol.app          single-validator LST
notch.fund           risk-capped memes (@Sam3dsol)

9. Closing

The dare was make whitepapers great again.

A great whitepaper is not one with more equations. It is one where every claim has an address you can query, every mechanism has a transaction you can decode, and every weakness is in the document rather than in a thread three months later.

The snakes are real, they are running, and two of them are currently spinning in an empty room. Both facts are in here.

Chronology is not causation. The floor protects value; it does not guarantee profit. Nothing here is financial advice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment