# The NASDAFUQ handbook

Start here. This file plus its links is the whole picture: what NASDAFUQ is, how the
reward system works end to end, what is deployed and proven today, and what a public
site or doc is allowed to say about it. If you are a fresh assistant or a new teammate
with no other context, read this file top to bottom before touching the site or writing
anything public-facing.

Date of writing: 2026-09-17. Where a fact is not yet true — because the work described
is in progress as this file is written — that is stated plainly rather than implied.

---

## 1. What NASDAFUQ is

NASDAFUQ is a meme coin built around one real mechanic: a fixed slice of its own trading
fees is used to buy a fixed basket of five other assets, and those assets are pushed
straight to NASDAFUQ holders on a schedule, automatically, with no claim button. The
site's tone is loud and joke-forward (a cursed terminal, rave visuals, an anime-nightclub
aesthetic); the mechanic underneath it is meant to be narrow, deterministic, and
independently checkable by anyone with an RPC connection.

The one-line mechanic: **trading fees → vault → split 20% each into five assets → pushed
straight to holders every epoch, no claim step.**

Everything below explains how that line actually works, what has been built and tested,
and what has not.

---

## 2. Current status, honestly

**This is a testnet-only prototype.** Nothing described in this repository is live,
legally cleared, audited, or backed by real value. Say so plainly in any public copy.

### What is deployed, and where

Deployed to **Robinhood Chain Testnet, chain ID 46630** (not the Robinhood Chain mainnet,
chain ID 4663). Manifest: `deployments/robinhood-testnet.json`; narrative record:
`deployments/robinhood-testnet.DEPLOYED.md`. Explorer:
`https://explorer.testnet.chain.robinhood.com`.

| Contract | Address |
| --- | --- |
| NASDAFUQ (test token) | `0x4d966612d5C31f86Ef5F79a707f269A8ef4eA76a` |
| Mock quote token (mUSDG) | `0x5Edc0d40523E09132c5a041D9c8dce7EB1580a1e` |
| FeeVault | `0x3650b295e5c8D321E27eF953fC7522db0Fb564F7` |
| PushDistributor | `0x12aD71C3Db2ee02Db1262A4EE00E151E7E771089` |
| HolderSnapshot | `0xf4644eFfFb34258096a5d664644b9E4584778C95` |
| FixedBasketPolicy | `0x15fA95D30742f7a8FCc9e53eb2Be0db715eee690` |
| AssetRegistry | `0xE5c0284F97dd5a0afB2FE6691aE524af84DB4418` |
| SafetyController | `0xE71b5625a6cd065dC973E688C57e560A7f1b79b5` |
| KeeperRegistry | `0x9039cc08dc486169759094E7447e5aBd4F5A9Eb6` |
| MockRouteAdapter | `0x2A755547965483eDBdb921D6248692bEF890927B` |
| MockPriceOracle (live oracle for all five) | `0xd1Fb4265C4c67394DE10d67C385ef97b07C98DE1` |
| ChainlinkPriceOracle (deployed, not live) | `0x955eEea7b6C33f9ba49B78D26A62b76e6761DcF9` |
| TwapPriceOracle (deployed, not live) | `0xaD0e8459d2ff3966cC27edEA2dBa578eEfAC85F9` |
| MockFeeMarket | `0xEbBD28C65C617e3202d3D6ec8B0C09Bb1c359A23` |

The five mock reward tokens (`mDELL`, `mAMD`, `mFLY`, `mUSAR`, `mQQQ`) are listed with their
weights in the manifest under `basket.assets`.

All 24 contracts (these plus the mock reward tokens and test doubles) are source-verified on the
Blockscout explorer; open any address with `?tab=contract`.
One disposable wallet (`0xd4a5E7289f5dD0Fb9BEEa3Fc6305Dc35c51A8Dca`) held every privileged
role for this first run: deployer, admin, keeper, treasury, feed operator.

This deployment carries the **v2** basket — mock reward tokens `mDELL / mAMD / mFLY /
mUSAR / mQQQ` — deployed 2026-09-17 with basket version
`0xe854756de2b356ab1ab481b4719ffc2cfa99080851a92c7723cf89c459d7e061`. Addresses,
parameters and roles: `deployments/robinhood-testnet.json` and
`deployments/robinhood-testnet.DEPLOYED.md`. All 24 contracts are source-verified on the
explorer. The FeeVault is `0x3650b295e5c8D321E27eF953fC7522db0Fb564F7`; the chain-native
start block is 120827954. The earlier v1 deployment (DDOG/APLD/FLY/USAR/QUBT) is
superseded and survives only in git history.

### What has been proven: the first v2 run

`scripts/e2e-testnet.sh` plus `scripts/finish-epoch.sh` ran two full epochs against the
deployment above and reconciled cleanly (70/70 then 128/128 checks,
`indexer/src/check.mjs`). All amounts below are the mock quote token (`mUSDG`) or mock
reward tokens, in human units — none of it is real money. Source: `data/tracker.json`.

| Epoch | Gross fees | Carried in | Net budget | Per-asset allocation | Result |
| --- | --- | --- | --- | --- | --- |
| 0 | 60 | 0 | 54 | 10.8 each | mDELL, mAMD, mUSAR purchased in one clip each (21.6 mReward each); **mFLY bought entirely by three drips** while the epoch was open (1.8 + 3.6 + 5.4 = 10.8, each exactly 20% of net-fees-so-far); **mQQQ forced rolled over** (route made unavailable on purpose); a holder's **mDELL push was forced to fail**, a duplicate batch moved nothing, and the retry paid it |
| 1 | 6,000 | 10.8 | 5,410.8 | 1,082.16 each | all five purchased (2,164.32 mReward each), including mQQQ; **mFLY took one 1,000 drip plus one 82.16 post-close clip** because its clip cap is 1,000 |

Two properties worth noting from epoch 0. First, mFLY's allocation was fully spent by
drips before the epoch closed, so the asset resolved at close and the epoch went straight
to distribution — the exact path an earlier review found would otherwise strand the
purchased inventory (fixed; `docs/ARCHITECTURE.md` §12). Second, mQQQ's rolled-over 10.8
mUSDG reappears as epoch 1's "carried in", so nothing was lost by the forced failure.

The keeper reserve on this deployment is configured at 1000 bps (10% of gross), inside
the immutable ≤2000 bps (20%) cap the contracts enforce. `net = gross + carried in −
reserve`, and each of the five allocations is `net × 20%`; the numbers above satisfy that
arithmetic exactly.

What this run proved, concretely: fee accounting adds up across both epochs; an
unavailable route rolls its allocation into the next epoch's `carriedIn` instead of
vanishing or becoming a sixth asset; a failed holder transfer stays retryable and does
not double-pay; a duplicate batch resubmission moves nothing; final on-chain reward
balances equal the sum of observed successful pushes exactly.

### What is NOT true

- This is **not live**. It is a testnet simulation with mock tokens that have no
  monetary value.
- This is **not legal clearance**. See §9 — gate G5 is open and blocking.
- This is **not audited**. No independent security review has happened (gate G3).
- **No real Stock Token or Tokenized ETF has ever moved.** Every asset in every run to
  date is a plain `MockERC20` minted for testing. Nothing here has touched Robinhood's
  actual DELL, AMD, FLY, USAR, or QQQ Stock Token / Tokenized ETF contracts.

---

## 3. The DAFUQ basket (v2)

**DELL / AMD / FLY / USAR / QQQ, 20% each.** The acronym DAFUQ is the last five letters
of NASDA**FUQ** — D, A, F, U, Q — one letter, one ticker, one weight, by construction.
QQQ is a Tokenized ETF, not a single-company stock: in any copy, the asset class for the
whole basket must be written **"Stock Tokens & Tokenized ETFs."**

Numbers below are from `docs/LIQUIDITY_SCREEN_2026-09-17.md`, a read-only mainnet
liquidity/feed screen (not investment advice, not a route approval — depth and prices
move constantly and must be re-checked before any activation).

| Slot | Ticker | What it is | Theme | Why chosen | Chainlink feed | Impact @1k / @10k USDG |
| --- | --- | --- | --- | --- | --- | --- |
| D | DELL | Dell Technologies Stock Token | AI servers / infrastructure | Deep enough pool, feed present | yes | +0.04% / +0.42% |
| A | AMD | AMD Stock Token | AI silicon / GPUs | Deep pool, feed present | yes | +0.01% / +0.14% |
| F | FLY | Firefly Aerospace Stock Token | Space launch | The deliberate degen slot — thin pool on purpose, handled with drip buys (§4) | no | +0.34% / +4.09% |
| U | USAR | USA Rare Earth Stock Token | Rare-earth supply chain | Deep pool, feed present | yes | +0.08% / +0.97% |
| Q | QQQ | Invesco QQQ Tokenized ETF | The Nasdaq-100, tokenized | Deep pool, feed present; also the joke ("NASDAFUQ pays you the Nasdaq") | yes | +0.01% / +0.06% |

Four of five assets fill 10,000 USDG inside 1% slippage and have a live Chainlink feed on
Robinhood Chain. FLY is kept anyway, deliberately, as the shallow-liquidity slot — see §4
for how the protocol buys it safely.

### Why v2 replaced v1

The original lore basket was **DDOG / APLD / FLY / USAR / QUBT**
(`research/nasdafuq-claude-build-handoff.md`). `docs/ROUTE_SCREEN_2026-09-17.md` and
`docs/LIQUIDITY_SCREEN_2026-09-17.md` screened it against real mainnet liquidity and
Chainlink coverage and found it unusable as designed:

- **APLD** did not fill even a 1,000 USDG purchase at an acceptable price on any pool
  found, and had no Chainlink feed.
- **DDOG** filled a 1,000 USDG purchase only thinly (+0.4% on one pool) and reverted at
  10,000 USDG; no Chainlink feed.
- **QUBT** is actually *deeper* than FLY (+0.04% at 1k USDG, +0.44% at 10k). It was dropped for
  one reason only: no Chainlink feed on Robinhood Chain. FLY, also feedless, was kept because the
  rocket is load-bearing lore and its thin pool is handled by drips; carrying two feedless slots
  was judged one too many. If a QUBT feed appears, revisit this.
- Of the original five, only **USAR** had a Chainlink feed on Robinhood Chain at all.

DELL, AMD, and QQQ replaced DDOG, APLD, and QUBT because all three are deep, liquid, and
feed-covered. FLY and USAR carried over unchanged. The basket still spells DAFUQ; it just
spells it with assets that can actually be bought and priced.

---

## 4. How an epoch works, step by step

All contract behavior below is `docs/ARCHITECTURE.md` §3 and §11 (revision E is the
current design; earlier revisions in §7–§10 are the record of how it got there).

1. **Deposits.** While an epoch is open, registered fee sources (on testnet:
   `MockFeeMarket`, simulating trades) call `depositFees`, adding to `grossFees[e]`. Only
   registered sources can do this; the set is admin-managed and append-only.

2. **Close.** A keeper calls `closeEpoch()`. This is where the epoch's numbers are fixed:
   - `keeperReserve[e] = grossFees[e] × keeperReserveBps / 10000` — an immutable,
     ≤20%-capped share reserved for keeper/gas costs, added to a balance withdrawable
     only to an immutable treasury address. (Testnet runs this at 10%.)
   - `carriedIn[e]` — quote rolled in from a prior epoch's unpurchased allocations and
     rounding dust.
   - `netBudget[e] = grossFees[e] + carriedIn[e] − keeperReserve[e]`.
   - Five `allocated[e][a] = netBudget[e] × 20%` amounts, one per basket asset. Any
     rounding remainder (at most a few wei across five floors) becomes dust, carried
     into the next epoch rather than lost.
   - `closeBlock[e] = block.number` at the moment of close. On Robinhood Chain (an
     Arbitrum-style rollup), the EVM's `block.number` inside a transaction actually
     returns the **parent chain's** block number, not the chain's own. The snapshot in
     the next step is instead defined at the chain-native block that contains the
     `EpochClosed` event — derivable from the event itself — so replay from logs stays
     reproducible. See `docs/ARCHITECTURE.md` §10 for the full story; it is the exact
     bug the first testnet run hit and fixed.

3. **Snapshot.** Off-chain, a keeper (or anyone) replays the NASDAFUQ token's `Transfer`
   logs up to the chain-native block from step 2, folds them into holder balances, and
   builds a Merkle tree (sorted-pair, OpenZeppelin-compatible double-hashed leaves). The
   output is a root, a `datasetHash` (hash of the sorted wallet/balance arrays), and a
   `totalEligible` sum. This computation is deterministic and reproducible by any third
   party with an RPC connection — see `indexer/README.md`.

4. **Commit.** A keeper calls `commitSnapshot(epoch, snapshotBlock, merkleRoot,
   totalEligible, datasetHash)`. The contract requires `snapshotBlock == closeBlock[e]`
   and the commit is immutable afterward. The contract only verifies membership in the
   tree it is told about — it does not itself verify the tree is correct — so
   reproducibility by outsiders is the actual check on a dishonest snapshot (see §5).

5. **Purchases (clip purchases).** After close, `purchase(epoch, asset)` may be called
   repeatedly. Each call ("clip") spends `min(remaining allocation, maxClipQuote)` for
   that asset, subject to protection checks — oracle not stale, adapter quote within
   `maxOracleDeviationBps` of the oracle's expected output, sufficient adapter liquidity,
   a `minOut` floor, a deadline. Every pre-buy read is wrapped so a revert anywhere
   resolves as a rollover with a labeled reason rather than reverting the whole epoch. A
   failed clip resolves the asset immediately: whatever was purchased in earlier clips is
   kept, and the unspent remainder rolls into `carryPending` (visible as
   `AllocationRolledOver`) for the next epoch. `finalizePurchases` requires all five
   assets resolved (purchased in full or rolled over) before it can run.

6. **FLY drips.** FLY's pool is shallow on purpose (§3), so its allocation is not bought
   in one clip. `dripPurchase(FLY)` may be called by the keeper while the epoch is still
   open, spending `min(maxClipQuote, dripCap − dripSpent)` where `dripCap` is 20% of the
   **net fees already received so far this epoch** — never a forward-looking estimate —
   subject to a minimum interval between drips. At close, the post-close clip spends
   whatever remains of the eventual allocation. The intent, in plain words: buy FLY in
   sips, not gulps, because a shallow pool punishes a single large buy.

7. **Finalize.** `finalizePurchases(epoch)` requires all five assets resolved. It folds
   any `inheritedInventory` (released by prior rollovers or below-minimum pushes) into
   this epoch's `distributable[e][a] = purchased[e][a] + inheritedInventory[a]`.

8. **Pushes.** `pushBatch` is **proof-gated and permissionless** — anyone holding a valid
   Merkle proof for a wallet (normally the keeper, but not exclusively) can submit it, in
   batches of at most `maxBatchSize`. The pro-rata formula is
   `distributable[e][a] × balance / totalEligible[e]`, floored. Amounts below
   `minPayout` are released to `inheritedInventory[a]` instead of paid, and are never
   retried. A failed transfer (e.g. a blocked destination) is retried up to `maxRetries`
   times by anyone; once that cap is hit, only the admin can roll the amount into
   `inheritedInventory[a]` for the next epoch's holders — never to an address. A
   duplicate push for an already-paid `(epoch, wallet, asset)` is a silent no-op.

9. **What "100% to holders" means.** It means 100% of **net distributable** fees: gross
   fees minus the published, immutable keeper/gas reserve (≤20%, capped in the
   contracts) and minus whatever execution loss (slippage) purchasing actually incurred.
   Both the reserve and the loss are emitted on-chain. It does not mean 100% of gross
   fees, and no copy should imply that.

Clip purchases and FLY drips are **testnet-proven** as of 2026-09-17: the run in §2
exercised a three-drip full fill, a drip-plus-clip fill against the 1,000 mUSDG clip cap,
and a single-clip purchase for the other four assets. The Chainlink and TWAP oracle
contracts are deployed on testnet (`contracts.chainlinkOracle`, `contracts.twapOracle` in
the manifest) and unit-tested, but every asset's live `oracleOf` is still the
operator-settable mock — wiring a real feed is production gate G2, not a testnet step.

---

## 5. Who can do what

Authority map (`docs/ARCHITECTURE.md` §4, `docs/RUNBOOK.md`):

| Action | Who | Notes |
| --- | --- | --- |
| Deposit fees | Registered fee source only | Testnet: `MockFeeMarket`. Sources are set once by admin, append-only. |
| Close epoch, purchase, drip-purchase, finalize | Keeper | Cannot choose an asset outside the basket, an adapter outside the registry, a recipient, or an amount — all of that is fixed by contract logic. |
| Commit snapshot | Keeper | Once per epoch; block is bound to the epoch's own close; root and dataset hash are public and independently reproducible. |
| Push a batch, or retry one | **Anyone** with valid proofs | Normally the keeper, but not restricted to them — this is the "permissionless, proof-gated" design that prevents a keeper from censoring a payout by simply not submitting it. |
| Pause purchases or pushes | Admin | Immediate; visible via `Paused`/`Unpaused` events. |
| Set an asset's status (Active/Paused/Unavailable) | Admin | Immediate; registration itself is append-only. |
| Rotate a route adapter | Admin, after a timelock | Publicly visible delay before it takes effect. |
| Roll a failed push into next epoch's inventory | Admin | Only once `maxRetries` is exhausted for that wallet/asset. |
| Withdraw the keeper reserve | Admin | Only to the immutable treasury address, only up to the reserve balance. |
| Recover an accidentally sent token | Admin | Only tokens that were never registered and are not the quote token. |
| Set a mock price/route rate (testnet only) | Feed operator | The most economically powerful role in the prototype — a dishonest or stale rate can waste an epoch's allocation, though it still cannot pay an unproven wallet or move inventory. A real, independently monitored feed is production gate G2. |
| Change the basket, its weights, or the reserve percentage | **Nobody** | These are immutable per deployed policy/vault. A new basket means a new policy and a new vault. |
| The website | **Nobody** | Read-only. It cannot choose a token, a recipient, a route, or trigger any of the above. |

### Fail-closed behavior

| Condition | What happens |
| --- | --- |
| A purchase route is unavailable, paused, or price-inconsistent | Quote stays in the vault; the allocation is recorded as rolled over and carried into the next epoch. Nothing is lost or silently dropped. |
| An oracle read is stale or deviates too far from the adapter's quote | Same as above — treated as a purchase failure, rolled over, never spent blind. |
| A reward transfer to a holder fails (e.g. a blocked destination) | The reward tokens stay in the vault; the failure is recorded and retryable by anyone up to a retry cap; after the cap, only admin can move it into next epoch's inventory. |
| A keeper goes offline | Fees keep accruing to the still-open epoch; funds sit safely in the vault; any other registered keeper (or the same one, later) can resume. |
| Pushes are paused | Nothing moves; the pause and its later lift are both events. |

---

## 6. Price anchors

A **feed** is an external, tamper-resistant source the vault reads to know roughly what
one unit of a reward asset should cost in quote-token terms, so a purchase can be checked
against it before it happens. Without a feed, a bad or manipulated route quote could spend
an entire epoch's allocation for almost nothing (the vault-side deviation check exists
specifically to prevent that).

- **DELL, AMD, USAR, QQQ** use **Chainlink** (`AggregatorV3.latestRoundData`), with a
  staleness check on `updatedAt` and normalization to 18 decimals. Chainlink is preferred
  wherever it exists because it is a widely used, independently operated, and monitored
  price source — not something the protocol itself has to run or trust blindly.
- **FLY** has no Chainlink feed (§3), so it uses a **Uniswap v3 TWAP** instead
  (`observe` over a time window), with a spot-vs-TWAP divergence bound: if the pool's
  current price has drifted too far from its own recent average, the TWAP oracle reports
  a stale timestamp on purpose, so the vault rolls the purchase over rather than trusting
  a possibly-manipulated momentary price.
- **Caveat:** on testnet, both of these are mocks — a `MockPriceOracle` and a mock v3
  pool with a settable `observe` return. No production Chainlink feed or real Uniswap
  pool has been wired to this system yet.

---

## 7. What the website shows

The site is `index.html` / `script.js` / `styles.css` / `assets/` at the repository root
— a static page with no backend, no wallet connection, no login, and no form that selects
a token, route, or recipient (`README.md`, `docs/ARCHITECTURE.md` §1,
`docs/THREAT_MODEL.md` §5). It cannot move funds because it has no entry point that could.

### Sections 00–04

| Section | Name | What it shows |
| --- | --- | --- |
| 00 | THE ACRONYM | The DAFUQ letter breakdown — ticker, theme, weight, one-liner per slot, plus the fees→vault→basket→snapshot→push pipeline as a tagline. |
| 01 | THE TERMINAL | A decorative synthetic price chart and a procedurally generated event-noise log. Explicitly not real market data. |
| 02 | THE BASKET | The five-asset board as cards, restating the fixed 20%-each rule and that testnet slots are mock tokens with no value. |
| 03 | THE MANIFESTO | Brand-voice copy — the "no utility, no financial advice, one loud website" bit and a radio-station decoration. Pure tone, no protocol claims. |
| 04 | THE PAYOUT LEDGER | The one section backed by real data: it renders `data/tracker.json`, produced solely by the indexer, read-only, on every page load (`cache: "no-store"`). |

### The five status labels

Every numeric value in the ledger carries exactly one of these (`docs/SITE_TRACKER.md`):

| Label | Meaning |
| --- | --- |
| `OBSERVED ONCHAIN` | Backed by an actual event with a transaction hash. |
| `ESTIMATED` | Derived by multiplying with a mock/reference rate (e.g. a top wallet's quote-value estimate) — never a transfer. |
| `PENDING` | Allocated but not yet purchased or pushed. |
| `FAILED` | A push that reverted and is still retryable. |
| `ROLLED OVER` | Quote or allocation that missed this epoch and moved to the next. |

### The offline state

If `data/tracker.json` is missing, unparseable, or has the wrong `schemaVersion`, the
ledger shows exactly this text and hides every data panel — it never falls back to demo
numbers:

> `LEDGER OFFLINE. NO DATA. NOTHING IS BEING SHOWN BECAUSE NOTHING WAS INDEXED.`

### Configuration

`site.config.js` holds the two things that flip the site from placeholder to live:
`social.xHandle` (the X/Twitter handle) and `chart.chain` + `chart.tokenAddress` (a
Birdeye chart embed). Both ship empty, and the site shows an honest "pending / slot
empty" state until they are filled in — it never fakes either.

### What the site has no authority to do

No wallet connect, no login, no admin panel, no RPC calls of its own, and no form of any
kind that selects an asset, a route, or a recipient. Its only network request for protocol data is
a fetch of `data/tracker.json`. One optional exception exists: when `site.config.js` is given a
Birdeye chain and token address, the terminal section embeds a Birdeye chart `<iframe>`, which is a
third-party request. It ships empty and shows "BIRDEYE SLOT: EMPTY — NO TOKEN DEPLOYED" until set.

---

## 8. What's real vs mock today

| Component | Testnet today | Production needs |
| --- | --- | --- |
| NASDAFUQ token | Plain `MockERC20` test token | A real deployed token / launch mechanism |
| Trading fees | `MockFeeMarket`, a simulated `trade()` call | A verified, real fee path from an actual DEX or launchpad into the vault |
| Reward assets | Five `MockERC20`s (`mDELL`/`mAMD`/`mFLY`/`mUSAR`/`mQQQ` once v2 redeploys) with no monetary value | The real Robinhood Stock Tokens & Tokenized ETFs at their canonical, freshly re-verified addresses (gate G2) |
| Price feed, DELL/AMD/USAR/QQQ | `MockPriceOracle` | Live Chainlink `AggregatorV3` feeds, monitored for staleness |
| Price feed, FLY | Mock TWAP via a mock v3 pool with a settable `observe` | A real Uniswap v3 pool TWAP with a working divergence check |
| Purchase route | `MockRouteAdapter` selling from pre-minted inventory at a configured rate | A verified Uniswap v3/v4 adapter with real depth checks before every purchase |
| Keeper / admin / treasury / feed operator | One disposable EOA holding every role | Separate, monitored identities; multisig admin with hardware signers (gate G4) |
| Snapshot & indexer | Manually run, reproducible replay scripts | Reliable RPC/WS provider, backfill, monitoring, alerting (gate G4) |
| Site data | A committed `data/tracker.json` fixture from a manual test run | A continuously regenerated feed from a real indexer, kept out of git |
| Issuer / jurisdictional authorization | None | Written authorization from the relevant issuer/partner plus a counsel-reviewed structure (gate G5 — see §9) |

The "testnet today" column above reflects the v2 deployment and the two-epoch run of
2026-09-17, including drips and clips. The two production-shaped oracle contracts exist on
testnet but are not the live price source for any asset; the route adapter is still the
configurable mock, never a real pool.

---

## 9. Production gates

Full detail: `docs/PRODUCTION_GATES.md`. Passing every local test does not make this
system legal, live, approved, audited, or "unhackable" — each gate below is a distinct,
open decision with its own evidence requirement.

- **G1 — Product specification.** Publish the basket addresses and version hash, the 20%
  rule, cadence, eligibility cutoff, minimum epoch threshold, keeper/gas reserve
  treatment, slippage/impact limits, failed-route and halted-asset rules,
  corporate-action treatment, custody model, and the exact meaning of "100% to the
  community." **OPEN.**
- **G2 — Canonical asset and route verification.** For every production asset at
  activation time: the exact canonical address from Robinhood's live registry, active
  status, no halt, a valid price feed, an approved route with real liquidity at expected
  size, and a successful minimum-output simulation. **OPEN** — the 2026-09-17 screens are
  evidence toward this gate, not a pass of it; depth and feeds must be re-checked
  immediately before any activation, not assumed from a prior screen.
- **G3 — Security review.** An independent audit of the contracts, plus malicious-token,
  stale-price, route-manipulation, multiplier, and keeper-downtime tests against the real
  route, with publicly verified source and parameters. **OPEN** — local unit/fuzz/
  invariant suites are prerequisites, not substitutes.
- **G4 — Production operations.** Reliable RPC/WS infrastructure, an indexer with replay
  and backfill, keeper monitoring and alerting, a multisig admin with hardware signers,
  separated deployer/admin/keeper/treasury identities, backups, and a public incident and
  pause procedure. **OPEN.**
- **G5 — Issuer and jurisdictional authorization.** Blocking. Robinhood's own
  documentation states its Stock Tokens may not be offered, sold, or delivered in the
  United States or to or from U.S. persons. **Nothing technical changes that.**
  Geography, labels, offshore deployment, pseudonymous wallets, or copy changes do not
  satisfy this gate — it requires written authorization from the relevant issuer or
  partner and a counsel-reviewed distribution structure. Until it closes, this project
  must not promise real Stock Token or Tokenized ETF rewards to anyone, and especially
  not to a U.S.-person audience.

---

## 10. Copy rules for any public site or doc

Apply these to every piece of copy — site, docs, social posts — about this project.

**Exact wording rules:**

- Write **"Stock Tokens & Tokenized ETFs,"** not "tokenized stocks" or "tokenized
  equities."
- State plainly that **mock rewards have no value** wherever mock tokens are shown or
  described.
- Never imply Robinhood **endorsement**, partnership, or approval.
- Never use the words **"legal," "approved," "live," "guaranteed,"** or
  **"unhackable"** about this project. (It is testnet, unapproved, not live, not
  guaranteed, and — like anything unaudited — not provably safe.)
- Label every estimate as an **estimate**. Never show an estimate as if it were a
  transfer.

**Phrases that are dangerous even though they are true.** Every one of these is accurate
somewhere in this document and becomes a false promise the moment it travels alone as a
headline, a tweet, or display type with the qualifier in a footnote:

- **"NASDAFUQ pays you the Nasdaq."** It is the punchline of the QQQ slot and it reads as
  a guarantee of index-linked return. Use it only with the mechanic and the testnet status
  attached in the same visual unit, or not at all.
- **"100% to holders."** True of *net distributable* fees. Three words alone is a
  different claim from the one the contracts make. If it appears, the definition appears
  with it, not below the fold.
- **The one-line mechanic** ("fees → vault → 20% each → pushed to holders") is written in
  the present tense because that is what the code does on testnet. Any public use needs
  "on testnet, with mock tokens" in the same sentence, not in a disclaimer block.
- **"rewards," "payout," "yield," "earn," "APY."** Not banned, but each one invites a
  reader to expect money. Prefer describing the mechanic. Never attach a number, a rate,
  or a projection to any of them.

**One thing this document cannot answer.** The production gates in §9 are about whether
the *reward assets* may lawfully be acquired and distributed. They say nothing about how
NASDAFUQ itself would be characterized. A token whose pitch is "hold this and receive
assets bought with protocol revenue" is materially different from a pure meme coin with no
yield, asset, or profit rights, and that difference is exactly what securities analysis
turns on. Nobody involved in this repository has answered that question, and no wording
choice settles it. Treat it as an open, blocking question for counsel alongside G5, and do
not let public copy imply it has been resolved. This paragraph is not legal advice.

**Brand voice notes** (this is the one section where the loud tone belongs — keep it out
of the explanatory sections above): cursed terminal chrome, anime-nightclub energy,
rave visuals, obnoxious neon, intentionally imperfect rather than polished-SaaS, and
funny enough that people want to poke around. The DAFUQ-letter bit — one ticker per
letter of the name, spelling out the joke — is the creative core of the whole brand; keep
building around it rather than replacing it. The one place that voice does **not**
apply is the numbers: the ledger section (§7, "04 / THE PAYOUT LEDGER") and any
accounting explanation must stay honest, legible, and free of jokes that could be
mistaken for a real claim.

---

## 11. Repository map and how to run things

| Path | What it is |
| --- | --- |
| `index.html`, `script.js`, `styles.css`, `assets/`, `site.config.js` | The static site. Browser-only, no secrets, no backend. |
| `contracts/` | Foundry Solidity workspace: protocol contracts, mocks, unit/fuzz/invariant/review tests, deploy script. |
| `indexer/` | Node (≥20, viem) tooling: snapshot builder, keeper CLI, event indexer, reconciliation checker. Reads keys only from environment variables at run time; never writes them. |
| `deployments/` | Public JSON manifests and deployment write-ups. No secrets. |
| `docs/` | Architecture, threat model, production gates, runbook, this handbook, and the point-in-time research screens. |
| `data/` | `tracker.json`, the one file the site reads. Produced by the indexer; a `data/tracker.sample.json` fixture exists for manual QA only and must never be copied into `data/tracker.json` for real. |
| `research/` | Product/technical handoff documents and earlier feasibility research. Evidence, not live authority. |
| `scripts/` | `e2e-local.sh` (anvil, one command), `e2e-testnet.sh` (Robinhood Chain Testnet, state-aware/resumable), and `finish-epoch.sh <epoch>` (completes a half-finished epoch: snapshot → commit → clip purchases → finalize → push → index → reconcile). |

**Run the contract tests:**

```bash
cd contracts
forge install foundry-rs/forge-std --no-git
forge install OpenZeppelin/openzeppelin-contracts@v5.1.0 --no-git
forge build
forge test
```

**Run the indexer's own tests:**

```bash
cd indexer && npm install && npm test
```

**Run the full local end-to-end proof (anvil, no real network, under two minutes):**

```bash
bash scripts/e2e-local.sh
```

**Run the testnet end-to-end proof** (against the deployment in §2; resumable if
interrupted):

```bash
bash scripts/e2e-testnet.sh
```

**Preview the site locally:**

```bash
python3 -m http.server 4173
# then open http://localhost:4173
```

Deployment manifests live in `deployments/`; the append-only event ledger the site reads
lives at `data/tracker.json`, written only by `indexer/src/index.mjs`.

---

## 12. Glossary

- **Epoch** — one full fee-accrual/purchase/distribution cycle: opens, accrues fees,
  closes, gets purchased, gets pushed.
- **Clip** — one bounded purchase call for one asset in one epoch; an allocation may be
  spent across several clips.
- **Drip** — a small, rate-limited clip made specifically for FLY while its epoch is
  still open, because its pool is shallow.
- **Feed** — an external price source (Chainlink, or a TWAP) the vault reads before
  approving a purchase.
- **Oracle anchor** — the reference price a feed provides, used to bound `minOut` and
  catch a manipulated or wildly wrong route quote.
- **Snapshot** — the deterministic holder-balance-and-Merkle-root record for one epoch,
  built by replaying `Transfer` logs to the block containing that epoch's close.
- **Merkle proof** — the piece of data a wallet (or anyone acting for it) presents to
  prove membership, and balance, in a committed snapshot.
- **Rollover** — quote or reward inventory that could not be used this epoch and is
  carried into the next one instead of being lost or improvised elsewhere.
- **Keeper** — the role that triggers close/purchase/finalize/commit; it cannot choose
  amounts, recipients, or assets — only when the machine advances.
- **Keeper reserve** — an immutable, capped (≤20%) share of gross fees set aside for
  keeper/gas costs, withdrawable only to a fixed treasury address.
- **Distributable** — the amount of a reward asset actually available to pay out for an
  epoch: what was purchased, plus anything inherited from a prior epoch's rollovers.
- **Push** — the permissionless, proof-gated transfer of a pro-rata reward share
  straight to a holder's wallet; the opposite of a claim.
- **Basket version** — a hash identifying one specific set of five assets and weights;
  changing the basket means a new version, a new policy, and a new vault.
- **USDG** — the quote/stablecoin asset used to buy the basket; mocked on testnet as
  `mUSDG`.
- **Stock Token** — Robinhood's tokenized representation of a single company's stock.
- **Tokenized ETF** — Robinhood's tokenized representation of an ETF (e.g. QQQ); grouped
  with Stock Tokens under the required phrase "Stock Tokens & Tokenized ETFs."
- **Testnet vs mainnet** — testnet (chain ID 46630) is where every scenario in this repo
  has actually run, with mock assets and no value; mainnet (chain ID 4663) is where the
  real Robinhood Stock Tokens and Tokenized ETFs live, and where nothing in this repo has
  been deployed or authorized to operate.
- **Parent-chain block number** — on Robinhood Chain (an Arbitrum-style rollup), the
  EVM's `block.number` returns the parent chain's (Ethereum Sepolia's, on testnet) block
  number, not the chain's own; log/event indexing must use the chain-native block instead
  (§4, step 2).

---

## 13. Further reading

- `docs/ARCHITECTURE.md` — the full architecture decision record, including every design
  revision and why it changed. §11 (revision E) is authoritative for the current design.
- `docs/THREAT_MODEL.md` — the adversarial critique that drove most of those design
  changes; read its status banner first, it explains which rows are historical.
- `docs/PRODUCTION_GATES.md` — the five gates in full, with exact evidence requirements.
- `docs/RUNBOOK.md` — exact commands and role separation for running the whole system
  locally or on testnet.
- `docs/SITE_TRACKER.md` — precisely what the site's ledger section reads, renders, and
  must never do.
- `docs/ROUTE_SCREEN_2026-09-17.md` and `docs/LIQUIDITY_SCREEN_2026-09-17.md` — the
  read-only mainnet research behind the basket v2 decision.
- `deployments/robinhood-testnet.DEPLOYED.md` and `deployments/robinhood-testnet.json` —
  the current testnet deployment record and manifest.
- `research/nasdafuq-claude-build-handoff.md` — the original product and technical
  handoff; still useful for the reasoning behind the fixed-basket, no-claim design, but
  superseded wherever it conflicts with `docs/ARCHITECTURE.md`.
- `indexer/README.md` — exact definitions for the Merkle tree, snapshot replay, and every
  keeper/indexer subcommand.
