Session — stage 2, life on the curve — closed 15 Sep 2026
How a buyer gets into a launch without already holding its quote asset. Everything in stage 2 is built except the router (O19): paying in ETH, ARB or USDC and being routed into the curve or pool. Research is done (below). Scope agreed 15 Sep 2026 — D22. Being built.
Read first, in this order
| This file, "What the research found" | The facts, verified on chain 14 Sep 2026 |
notes/FEATURES.md — Stages 0, 2 and 4 | The router line appears in stages 2 and 4; the stage 0 gaps below reach into two ✔ lines |
notes/DECISIONS.md — O19, D18, D19, D20, D21 | The router question and the pairing layer it routes into |
../launchpad/src/ZapRouter.sol | RHUB's live router — the template |
contracts/src/curve/BondingCurve.sol, contracts/src/assets/BasketWrapper.sol | buy/sell/quoteBuy, and mint/previewMint |
notes/references/reality-rtokens.md | Where rToken liquidity actually is |
The uniswap-trading plugin covers the Universal Router, Permit2 and v4 swap encoding.
Already decided — constraints
- The router is never load-bearing. The curve and pool stay directly callable.
- SafeERC20 throughout. Trading in the pair itself already works without a router.
- D19: anything that knows about baskets stays out of the core;
make check-boundariesstays green; the stage 0 and stage 1 suites pass unchanged. - Curve fees are D17's. A router adds none unless that is decided.
What the research found
Ordinary quotes route today.
- RHUB's
ZapRouteris live: ETH → ARB on Uniswap v3, then the curve or the v4 pool, switching oncurve.graduated(). Custody-free, no owner. But per launch, and its v3 leg has no minimum of its own. - Uniswap v3 on Arbitrum (balances, not depth): WETH/USDC 0.05% ~6,750 WETH + 19.1M USDC; WETH/ARB
~188 WETH + 8.7M ARB; WETH/wBTC
5,400 WETH + 297 wBTC. ARB/USDC is thin ($5.5k) — route via WETH. - Universal Router
0xa51a…81a3, SwapRouter020x68b3…Fc45and Permit2 are deployed. - After graduation our pools have no hook, so Uniswap's router and aggregators already reach them. Ours is only indispensable while a launch is on the curve.
Stocks do not route — our contracts cannot acquire rTokens.
- Reality's docs ("Onchain Swap",
/info/ref/protocol/attestation) describe the protocol path: fetch a signed attestation fromPOST /api/v1/rwa/wallet/attestation, then callTokenManager.mintWithSignaturein the same transaction. - On chain,
mintWithSignaturerevertsUserNotRegisteredfor any caller missing from Reality's identity registry0x36e2D13013b48862A818ec3394826F65c94618d4— including Bitget Wallet's executor. Reality's own RFQ contract passes that gate and fails only on the signature. - Retail buys today go Bitget Wallet router
0x6889…→ executor0xBc1D…c973→ Reality RFQ contract0xea13017FB146c3245Bc032B5ba590460B01F24B1, whoseswapis itself gated by acallerallowlist. - So ETH → stock needs Reality to onboard us: KYB for our entity, API keys, our router registered. That is a business dependency, and it makes us the participant routing retail into a product Reality sells only to KYC'd non-US persons — a compliance question, not just an engineering one.
- Minting is 24/5; a stock route closes at weekends and between sessions (
TokenManager.marketHours()).
Gaps this exposed in stage 0 — settle before scoping the router
- "Anyone can mint and redeem baskets" is ✔ in
FEATURES.md, but only rToken holders can. A contract, a router or a non-Bitget user cannot obtain rTokens on chain. The people who can keep a basket's price honest are, in practice, Bitget users. The marker overstates it. - A stock-paired launch has no on-chain way in for most buyers. Buying needs the basket, the basket needs rTokens, and rTokens come only from Reality or Bitget. Stage 0 proved the mechanism end to end with a whale's rNVDA on a fork; it never asked where a normal buyer's rNVDA comes from.
- Both are liquidity and access facts, not contract bugs. No stage 0 contract is wrong; what may be wrong is the claim that stock pairing is usable.
Decided 15 Sep 2026
- Stage 0 gaps: the mint line in
FEATURES.mdis ~, caveated to rToken holders. Reality onboarding is dropped for v1, not parked — a stock-paired launch is reachable only by holders. - Router scope (D22): ordinary quotes only; a v3 path supplied by the caller plus one final minimum; one shared router, UUPS and owned; excess on a crossing buy refunded in the quote.
- The developer's frame: build the concept end to end, refine incrementally afterwards. Stage 2 closes when the router lands.
Build plan
- Done. Router, curve leg: ETH or token → v3 path → quote →
curve.buy, and the reverse. 11 local tests against a mock v3; each guard mutation-checked against the test that names it. - Done. Pool leg: the same calls switch to the v4 pool on
curve.graduated(). Proved for a quote sorting either side of the token, each trade equal to a direct swap in that pool. - Done. Fork tests against live SwapRouter02 and PoolManager: ETH into an ARB launch on the curve and in the pool and back to ETH; ARB → WETH → USDC into a USDC launch and back. Every amount exact, each leg measured directly and undone. Block 504,000,000; 0.05% is the deepest tier for both WETH/ARB and WETH/USDC there.
Not this session
Pool fees (O17), hooks, the interface, anti-snipe, security, dividends (O18).
Found while building
PartialFillhas no test. A swap stopping at the price limit would strand the unspent input, so the router reverts; the migrator's range is full, so draining it is not practical to set up.
Next
Closed. STATUS.md updated; the next thread is the developer's call.