Five dozen tokenization reports. Twenty questions.
A timed, single-page knowledge check built on the same source folder as the RWA Research Snapshot — the RWA & tokenization research published Apr–Jun 2026. Not the headlines: the figures that quietly contradict each other, the products nobody can name, and the details most people skim past.
Every question carries a sourced explanation. There's a clock, a streak multiplier, a 50/50 lifeline, and a shareable result card.
No build step, no dependencies, no framework, no backend. One file — index.html. Everything below runs client-side.
Three toggles on the cover, all independent:
| Setting | Options | Effect |
|---|---|---|
| Mode | Random 20 · Daily challenge | Daily seeds the RNG from the date — same 20 questions, same order, same shuffled options for everyone that day |
| Topics | Mixed · Market · Issuers | Mixed draws 10 from each category; a single topic draws all 20 from one |
| Pace | Chill 45s · Normal 28s · Blitz 15s | Per-question countdown. Running out reveals the answer and scores zero |
Twenty questions per run, drawn from a bank of 68 — so no two random runs look alike.
Keyboard: 1–4 to answer, Enter or Space to advance.
gained = round( (100 + speed) × multiplier )
speed = round(120 × timeRemaining / duration) → 0–120, answer faster to earn more
multiplier = 1 + 0.1 × min(streak − 1, 10) → 1.0× to 2.0×, caps at an 11-answer streak
A perfect, instant, unbroken 20 tops out at 7,590 points. Wrong or timed-out answers score nothing and reset the streak to zero. The streak counter bursts confetti at 3, 5, 10 and 15+.
The 50/50 lifeline is once per run and multiple-choice only — it dims two wrong options and is disabled on the other question types.
Four formats, mixed into every run. The draw guarantees a minimum of the non-multiple-choice ones (~30% of each category's slice, floor of 2) so a run never comes out as twenty identical MCQs — see drawCat() at index.html:656.
| Type | Count | How it works |
|---|---|---|
| Multiple choice | 53 | Four options, shuffled at render. Correct answer flashes green, wrong shakes |
Higher / Lower (hl) |
5 | Two labelled sides, pick the bigger. Values stay hidden until you commit |
Guess the number (slider) |
5 | Drag and lock in. Scored on relative error against a per-question tolerance (15–30%), and the reveal tells you how close you got |
Order by size (order) |
5 | Tap four items largest-first. All-or-nothing — the reveal ranks and colours each slot |
The end screen grades you on the 20:
| Score | Persona |
|---|---|
| 18–20 | The Insider — could have written the report |
| 15–17 | The Allocator — would survive a due-diligence call |
| 11–14 | Directionally Correct — right shape, fuzzy decimals |
| 6–10 | The Skimmer — you've read the executive summaries |
| 0–5 | The Tourist |
If your market and issuer scores diverge by 3 or more, the persona picks up a line naming which side is the gap.
- Emoji grid — 🟩/🟥 in rows of five, Wordle-style
- Share on X — opens a tweet intent prefilled with score, persona, grid and points
- Copy result — same text to the clipboard, with an
execCommandfallback for older browsers - Download card — renders a 1200×630 PNG on a
<canvas>(paper background, score, persona, result squares, R3 mark), waiting ondocument.fonts.readyso Fraunces and Inter land in the image rather than the fallbacks. SeemakeCard()at index.html:805
Best score and play count persist in localStorage (rwaquiz_best_pts, rwaquiz_played, rwaquiz_sound). Nothing leaves the browser — there is no analytics, no backend, no network call after the fonts load.
68 questions, split exactly 34 market / 34 issuer, each with a sourced one-paragraph explanation shown immediately after you answer.
- Market parameters — the definitional fights: free-float vs. full settlement layer, the 2030 forecast spread ($400B → $14T), penetration at ~1 basis point, who published which number.
- Issuers & products — the fine print: BUIDL vs. USYC vs. Figure's HELOC token, ERC-3643 and why compliance tokens can't sit in Aave, Spiko's AMF-supervised fund suite, Apex/Tokeny, bStock trade sizes, Tether's Treasury book.
- Castle Labs (Jun 2026) — a later block on DeFi utilisation: only ~$3B of a ~$28B market is actually deployed, reinsurance is the highest-utilisation category, tokenized "commodities" is really just tokenized gold.
Sources cited per answer — Binance Research, BeInCrypto × rwa.xyz, Pantera, CoinGecko, Citi, BCG, Castle Labs and others.
index.html the entire app — markup, design tokens, CSS, 68-question bank, game engine, PNG card renderer
That's it. There is no package.json, no config, no CI.
python3 -m http.server 8000Then open http://localhost:8000. Opening index.html straight off the filesystem works too — only Google Fonts needs network, and the layout degrades to Georgia/system sans without it.
Any static host serves it as-is: GitHub Pages, Netlify, Cloudflare, an S3 bucket. Push index.html to the root and you're done — no build command, no output directory.
Note that unlike the sibling snapshot repo, there's no wrangler.jsonc and no .gitignore here. If you want the Cloudflare deploy path, copy both across.
Questions live in the BANK array at index.html:322, grouped by comment banner. Every entry needs c ('market' or 'issuer'), q (the prompt), e (the explanation) and s (the source line). The rest depends on type.
Multiple choice — no type field. a[0] is always the correct answer; options are shuffled at render, so write them in any order you like as long as the right one is first:
{c:'market', q:'Distributed (free-float) tokenized RWA value in May 2026:',
a:['$31.4B','$12.8B','$58.9B','$94.2B'],
e:'Distributed value hit $31.4B – up from ~$21.5B at the start of 2026…',
s:'Binance Research · May 2026 (RWA.xyz data)'}Higher / Lower — val is compared numerically and rendered with fmtB() (billions, rolling to $XT above 1000), so keep both sides in the same unit:
{c:'issuer', type:'hl', q:'Bigger tokenized product by value?',
left:{label:'Circle USYC', val:2.96}, right:{label:'BlackRock BUIDL', val:2.42}, e:'…', s:'…'}Slider — tol is fractional, not absolute: 0.15 means within 15% of answer. min/max/step set the track, dec the displayed precision, prefix defaults to $:
{c:'market', type:'slider', q:'Guess Citi’s 2030 tokenized-securities forecast:',
answer:5.5, min:0, max:20, step:0.1, dec:1, suffix:'T', tol:0.2, e:'…', s:'…'}Order — four items, scored strictly descending by val, all-or-nothing:
{c:'market', type:'order', q:'Order these 2030 forecasts, largest first:',
items:[{label:'BCG', val:14000},{label:'Citi', val:5500},…], e:'…', s:'…'}Two things to keep an eye on when you add questions. The 34/34 category split is what makes the Mixed draw land 10 and 10 — skew it badly and one topic starts repeating. And each category needs enough non-MC entries to satisfy the specials floor: single-topic runs ask for 6 of them out of a 20-question draw, and the current bank has 8 market / 7 issuer, so there isn't much headroom before the draw quietly falls back to filling with multiple choice.
Design tokens are CSS custom properties in :root at index.html:12 — paper #F2EBDD, ink #1A1816, accent #C44A36, green #4F7A54, highlight #F5E69A, with Fraunces for display and Inter for text. The same palette drives the canvas card, but hard-coded as hex literals in makeCard() — change a token and you have to change it there too.
Sound is off by default (WebAudio oscillators, no audio files): a rising triad on correct, a low saw on wrong, a tick in the last five seconds, a fanfare above 14/20. The preference persists across sessions.
Motion respects prefers-reduced-motion — confetti, point floaters and the score count-up all switch off.
- Daily mode uses the local date, not UTC.
todayKey()readsgetFullYear/getMonth/getDateoff a localDate, so "same 20 for everyone today" holds within a timezone but not across them — players either side of a date line get different sets at the same instant. - The answer key is in the page source.
a[0]is always correct, and the higher/lower and order values sit in the DOM atopacity:0rather than being withheld. That's inherent to a no-backend quiz; anyone who opens devtools can win. Fine for a knowledge check, not for anything scored competitively. - No Open Graph or Twitter card tags — despite the built-in share buttons. A shared link renders bare, and the nicely-rendered PNG card has to be attached by hand. Four
<meta>tags in<head>would fix it. - The run length is fixed at
N_TOTAL = 20(index.html:611) and referenced in copy throughout — changing it means touching the strings too.
Prepared by Mike Blank · figures as of 1 Aug 2026. Sources cited per answer.