runner.exchange — A bonding-curve launchpad with no exit hatch
August 3, 2026
Overview
runner.exchange is a token launchpad on Robinhood Chain. Anyone can launch a token instantly. Buys and sells are priced by a bonding curve, and when a curve collects its graduation threshold the token graduates: the curve converts into a permanently locked liquidity pool owned by the launchpad. No LP token is minted, and there is no withdrawal path.That last sentence is the entire product. Every design decision follows from it.I built both halves: the Solidity contracts and the trading interface.
The problem it is built against
The launchpad category has a reputation problem it has earned. The standard failure is the rug: liquidity is provided, the token trades up, and then the liquidity leaves. Most platforms address this with promises — a lock period, a multisig, a team commitment, an audit badge.The premise here is that a promise is the wrong instrument. If liquidity can be withdrawn, the question is only whether someone chooses to. So the graduated pool is internal to the launchpad contract and has no withdrawal function at all. Not a timelock. Not a trusted custodian. There is no code path that removes it.The tagline on the site states the mechanism plainly: every token earns its exit. A token trades on its curve until it has collected enough real volume to graduate, and then its liquidity is locked forever and trading continues against it.
Design in an adversarial context
Designing a trading interface is unlike designing most products, because a share of your users are actively hostile and the rest are moving fast with money.
The interface is monospaced and typographic, closer to a terminal than a fintech app. That is not nostalgia. Numbers in a proportional font are harder to compare at a glance, and this is a screen where misreading a number costs money.
Mechanics are stated, not marketed. The information page leads with how graduation works and what the owner can and cannot do, rather than with returns. In a category built on hype, describing the constraints is the pitch.
Loading states are designed, not absent. Chain data arrives late and out of order. Skeleton cards and an explicit "loading feed" state exist so a slow block never reads as a broken page or, worse, as a zero balance.
The launch flow is a form that explains itself. Choosing between bonding-curve mode and instant-listing mode is the most consequential decision a creator makes, so both options are described in full at the point of choice rather than in documentation.
What the owner cannot do
A launchpad's trust model is defined by its admin powers, so those are worth being explicit about. The owner can adjust the post-graduation fee tier schedule, bounded on-chain at 3% total, and that does affect live pools — an honest consequence of dynamic fees.The owner cannot pause trading, touch curve ETH or locked pool reserves, mint or move any token, alter a live curve's snapshotted parameters, or upgrade the contracts. After deployment, ownership sits with a multisig Safe behind a timelock controller, and the deployment runbook treats the handoff as a gate: the system is not considered live until runner.owner() == timelock has been verified on-chain.Writing down what you cannot do is more useful than listing what you promise not to.
Architecture
Contracts. A Foundry project built with pinned toolchain versions and compiled via-IR. A singleton launchpad contract holds both the curve logic and the locked automated market maker, with per-launch fixed-supply ERC-20 tokens. Curve parameters must satisfy an exact integer-landing equality that is checked on-chain — they are generated by a script, never written by hand, so a curve cannot be deployed in a state where its graduation maths does not close cleanly.Testing. Unit, fuzz and invariant suites across the curve, the hook and the router, including a dedicated audit test file and a pin-poisoning test. Invariant testing matters more than unit testing here: the property that must hold is not "this function returns the right number" but "the contract's balance always covers every live curve, every locked pool and all uncollected fees". An operations script asserts exactly that solvency property against the deployed contract.Indexer. The trading interface does not hit the chain once per user. A shared in-memory snapshot is refreshed on a timer and served to every client, with a configurable reorg depth so a reorganised block does not surface as phantom trades. Three environment variables trade latency against RPC cost, with the server sync interval as the only real cost knob. In production the snapshot persists to Netlify Blobs, where losing it costs a rescan and nothing else.
Technologies used
Contracts: Solidity 0.8.30 with Foundry, compiled via-IR; unit, fuzz and invariant test suites.
Frontend: Next.js with wagmi v2 and viem for chain interaction, TanStack Query for data, lightweight-charts for price charts.
Extras: LiveKit for live audio in the trading rooms, React Three Fiber for visual pieces, Supabase for off-chain data.
Infrastructure: Netlify with Blobs for the indexer snapshot; a Safe behind a timelock controller as contract owner.
Operations: deployment runbook, on-chain verification bundles, and a solvency check script.
Challenges and learnings
Permanence has to be structural. It would have been far easier to ship a timelocked withdrawal and call it locked liquidity. Removing the function entirely is a harder design because it forecloses options — including fixing your own mistakes. That is the cost of the guarantee being real, and it is the reason the parameter generation and invariant testing had to be as rigorous as they are. You cannot patch a pool you cannot touch.Chain data is not a database. Blocks reorganise, RPC endpoints rate-limit, and a naive interface that polls per user turns a popular launch into a self-inflicted outage. The indexer with a shared snapshot and an explicit confirmation lag was the difference between a demo and something that survives its own traffic.The best security work is legible. A security review document nobody reads protects nobody. Stating the admin powers as a short bounded list — including the one power that is retained and why it affects users — does more for trust than an audit badge, because a reader can actually check it against the code.
Outcome
A launchpad whose central claim is verifiable rather than promised: liquidity that graduates into a pool with no exit, fees that keep flowing after graduation, and an owner whose powers are a short list a skeptic can read in a minute. The interface is built for the person reading numbers quickly, and the contracts are built for the person trying to break them.