Architecture

The system splits in two: an on-chain half that's autonomous once deployed, and an off-chain half that decides when to act.

  OFF-CHAIN ── runs 24/7 ─────────────┐   ON ROBINHOOD CHAIN ── autonomous ────────────┐
                                      │                                                │
  KEEPER                              │   NAVOracle (one per LT)                       │
   ├─ holds/rebalances each perp on   │      ▲ postNav(nav, sig)  EIP-712              │
   │   Lighter (margin in USDG)       ├──────┘      │ latestNav()                      │
   ├─ computes NAV = equity / supply  │             ▼                                  │
   ├─ signs + posts NAV ──────────────┤        LTVault  ── mint/redeem at NAV          │
   ├─ harvest / expand / reanchor ────┤             ▲ mint / redeem                    │
   └─ buyback & burn ─────────────────┤   SingleSidedMemeV4  ── owns every coin's LP   │
                                      │                                                │
   trader ── ETH ──▶ MinimalV4Router ─┼──▶  V4 pool (LpGuardHook)  ──▶  MEME           │
                                      └────────────────────────────────────────────────┘

The contracts

SingleSidedMemeV4 is the launcher. It creates coins, owns every coin's liquidity position, and executes harvest, expand, reanchor and buybackAndBurn, tracking per-coin backing in backingLtShares. LpGuardHook rides every pool it creates. LTFactory is the owner-gated registry that deploys a NAVOracle and an LTVault per leveraged token and exposes the isLt() gate. NavBatchRelay posts the whole fleet's NAV in one transaction per sweep, and MinimalV4Router is the swap path into the gated pools.

Everything here is immutable once deployed. There's no upgrade proxy on the launcher, no admin function that can move a user's tokens, and no path by which the keeper can withdraw a coin's pool to itself.

The keeper

The keeper is a supervised daemon. Each sweep it reads the fleet, decides what each market needs, and submits the resulting transactions. What makes it scale is one observation: the hedge is O(underlyings), the pools are O(coins).

Many coins can share one underlying's perp market, so the Lighter and NAV side scales with the number of markets — tens — while the pool side scales with the number of coins, potentially hundreds. Those are two different problems, so they're two different services. Hedge coordinators own a group of markets and their own Lighter account exclusively; exclusive ownership of a signer is the invariant that prevents nonce races, which produced the worst bugs found in live testing. Pool workers shard across coins and never touch Lighter — they read the published NAV and manage their pools locally, with no shared critical state.

Isolation

Isolation is the load-bearing property of the design. Each LT has its own vault, oracle and margin, so one wiping out can't freeze or drain another. Each live coin holds its own isolated perp position where slot capacity allows, so its outcome is its own bet rather than a stranger's, and slots are released only on proof that the position is closed and the margin is home. Each market's position is owned by one Lighter sub-account with one signer and one serialized nonce stream.

Why the pools are LP-gated

In live testing on canonical permissionless pools, a sniper LP'd its own position at the active tick — measured at roughly 23× the protocol's liquidity, 100% third-party — and captured the entire revenue path. Buys filled against the parasite's inventory, the price stayed pinned above the protocol's ladder, and the coin's hedge stopped growing. The keeper could detect and starve that, but it could not evict it.

LpGuardHook removes the vector at the root: beforeAddLiquidity reverts for every sender except the launcher, and beforeInitialize is gated the same way so no foreign pool can enroll the hook and wear it as a badge. The protocol is a pool's only possible LP by construction rather than by policy. Swaps carry no hook at all.

The accepted trade-off: these pools live on the protocol's own V4 PoolManager, and aggregators and chart sites index the canonical Uniswap deployment. They do not appear on third-party trackers, and the canonical SwapRouter02 cannot reach them. Coins chart through the app and its subgraph instead. Swapping remains permissionless for any V4-aware router.

Fail-safe posture

The system is built to stop rather than to guess. A NAV stale past the bound makes the vault's money path revert and freezes mint/redeem. A keeper offline means no harvest, expand or buyback, while pools keep trading on existing depth. Missing buyback data means no buyback, never a guess. A slot unwind that stalls is marked STUCK, alerted, and kept occupied rather than silently recycled. A redeem exceeding the buffer is queued and settled on margin recall rather than reverted.

Verification

Solidity suites under test/ include full system-integration tests running a real signed oracle → vault → pool → router → harvest → buyback path. A pure Python risk engine with deterministic trajectories and an acceptance suite reproduces the numbers in NAV, decay & funding offline. Live validation runs on Robinhood Chain and Lighter mainnet against real capital are logged in the repository, including the failures that produced the current design.

The perp leg runs on Lighter under a known account and the signed hedge equity is published on-chain per LT, so the backing is auditable against the venue rather than asserted by a dashboard.


Deployed addresses — Robinhood Chain (chainId 4663)

SingleSidedMemeV40x4B6CB7c3Fd2B0378C121C11265FAf4a7F19F10B5
PoolManager (V4)0xA999FFb2e9046f11670e7d8C62e0523F46B036bb
MinimalV4Router0xbD6D61f11C7Bf337Bf6cAB1CF8a1A05642518506
V4Quoter0x3ed514d12679dd627638a6E3921EaD6033bdce88
LTFactory0xc96c76898d2642a7c57d0f7676acb9409e00504c
NavBatchRelay0x1AB833fFEa5BF661c369fBAb5D55f665AAcDb179
USDG (settlement, 6 dp)0x5fc5360d0400a0fd4f2af552add042d716f1d168
Uniswap V3 SwapRouter02 (WETH/USDG leg)0xcaF681a66D020601342297493863E78c959E5cB2
Uniswap V3 QuoterV20x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7
Hedge venueLighter, account 733718

LpGuardHook's address is CREATE2-mined for its permission bits and bound one-shot to the launcher — read it from SingleSidedMemeV4.lpGuard(). Per-LT vault and oracle addresses come from LTFactory.