Developer Docs
Everything you need to launch, trade and build on Robin Labs Pad, a creator-first memecoin launchpad on Robinhood Chain. One-transaction launches into a real Uniswap v3 pool, a bonding-curve, a ceiling-only graduation, and a permanently-locked floor: the Bond.
01 · Start hereOverview
Robin Labs is a set of audited, non-upgradeable contracts. There are no proxies and no admin backdoors, the platform owner can point new launches at a fee wallet and nothing else. A launch is a single transaction that deploys the token, seeds the bonding curve, opens trading, and (optionally) executes the creator's own opening buy, atomically.
- Real DEX from block one. Every coin is a genuine Uniswap v3 pool, so it's chartable on DexScreener the moment it launches.
- Approval-free buys. Buying sends native ETH, no token approval. Selling needs one exact-amount approval to the router (never infinite, never to a personal wallet).
- Fees ride the protocol. The 1% is the Uniswap LP fee tier, collected in-protocol, there's never a side-transfer bolted onto your transaction.
- Un-ruggable graduation. At graduation, liquidity is posted to the Bond and locked forever, with a WETH floor that only deepens with volume.
01 · Start hereNetwork & addresses
| Key | Value |
|---|---|
| Chain | Robinhood Chain (Arbitrum Orbit L2, EVM) |
| Chain ID | 4663 (0x1237) |
| Currency | ETH (18 decimals) |
| Public RPC | https://robinhoodchain.blockscout.com/api/eth-rpc |
| Explorer | https://robinhoodchain.blockscout.com |
| Per-tx gas cap | 16,777,216 (2²⁴), relevant if you batch calls |
Contract addresses (live)
| Contract | Address | Role |
|---|---|---|
| CurvePadFactory | 0x8aa92d5297fEC45cbC7F16A32F4aed5D3AC58074 | One-call launch entrypoint |
| PadRouter | 0xA6BaAB820809C7fC8350311776627298f91F07eC | The swap desk, every buy/sell goes through it |
| FeeConfig | 0x064D977B66FCC29256510dBCD8cC0C51bBb2De14 | Owner-governed fee dial, LP + swap split, retunable with no redeploy |
| FloorCoopFactory | 0x564EDF561Bed46C972d5D44D84f5FAc9C5118668 | Deploys the per-coin FloorCoop LP vaults |
| PlatformFeeSplitter | 0xca0EfD87B983CdeF56459051ecBE91aA5C87E17a | Routes the platform's cut (the $ROBIN buy-back split) |
| WETH | 0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73 | Canonical wrapped ETH |
| UniswapV3Factory | 0x1f7d7550b1b028f7571e69a784071f0205fd2efa | The real v3 factory each pool is created on |
CurvePool and Bond addresses are per-coin, you get them from the factory's Launched event or recordOf(token), and from router.bondOf(token).
01 · Start hereArchitecture
A coin's whole life touches four contracts:
| Contract | Owns |
|---|---|
| CurvePadFactory | Deploys the token + curve + pool in one tx, registers the coin with the router, runs the anti-snipe opening buy. |
| CurvePool | The bonding curve, a single-sided v3 position spanning [startTick → gradTick]. Owns graduation (ceiling-only at ~4.2 ETH). |
| PadRouter | The only trade path. Applies the 1% fee in-protocol, splits it to escrows, exposes dev fee controls. |
| Bond | Protocol-owned floor posted at graduation and locked forever: Sherwood (full-range LP), Bounty (WETH buy-wall), Ambush (token sell-wall). Fees compound back in via poke(). |
02 · Contracts & ABICurvePadFactory
The launch entrypoint. launch() is payable: any ETH you send is the creator's own opening buy, executed atomically before public trading opens. It's uncapped: it climbs the curve up to the graduation ceiling, and any ETH beyond what fills the curve is refunded.
// The launch params tuple. tax.projectWallet receives the creator's sell fee.
function launch(
(string name, string symbol, address dev,
(uint16 buyBps, uint16 sellBps, uint16 walletBps,
uint16 floorBps, uint16 burnBps, address projectWallet) tax) p
) payable returns (address token, address curve, address pool)
function tokenCount() view returns (uint256)
function allTokens(uint256 index) view returns (address)
function recordOf(address token) view returns (address token, address curve, address dev, uint256 at)
event Launched(address indexed token, address indexed curve, address indexed pool, address dev, uint256 devBought)02 · Contracts & ABIPadRouter
Every trade goes through the router. Buys send native ETH (no approval); sells need one exact-amount approval to the router. The fee split happens inside, no side transfers.
function buy(address token, uint256 minOut) payable returns (uint256 tokensOut) function sell(address token, uint256 amountIn, uint256 minOutEth) returns (uint256 ethOut) // reads function configOf(address token) view returns ( (address pool, address curve, address projectWallet, uint16 buyBps, uint16 sellBps, uint16 walletBps, uint16 floorBps, uint16 burnBps, bool set) ) function devEscrow(address token) view returns (uint256) // creator's uncollected sell fees (wei) function bondOf(address token) view returns (address) // creator-only fee controls (projectWallet) function withdrawDev(address token) // collect escrowed sell fees to the wallet function burnDev(address token) // buy + burn with them instead event Bought(address indexed token, address indexed buyer, uint256 ethIn, uint256 fee, uint256 tokensOut) event Sold(address indexed token, address indexed seller, uint256 tokensIn, uint256 fee, uint256 ethOut) event FeeSplit(address indexed token, uint256 platform, uint256 deferred, uint256 platformCut, uint256 dev, uint256 floor, uint256 burn)
02 · Contracts & ABICurvePool
The bonding curve and graduation. Read it for progress up the curve; call graduate() (permissionless) to post the Bond. Graduation happens at ONE place only: the full ceiling (~4.2 ETH raised). There is no early graduation and no timeout: below the ceiling the coin simply keeps trading, and sellers can always exit.
function pool() view returns (address) // the Uniswap v3 pool function dev() view returns (address) function bond() view returns (address) // zero until graduated function seeded() view returns (bool) function graduated() view returns (bool) function ready() view returns (bool) // true only at the full ceiling function seedTime() view returns (uint64) // geometry - ticks along the curve (price rises left→right) function startTick() view returns (int24) // curve start (~$3.4k FDV) function gradTick() view returns (int24) // ceiling - the ONLY graduation point (~4.2 ETH) function graduate() // permissionless once ready() event Seeded(int24 curveLo, int24 curveHi, uint128 liquidity) event Graduated(address indexed bond, uint256 raisedWeth, uint256 leftoverToken)
02 · Contracts & ABIBond
The floor, posted once at graduation and locked forever. Anyone can call poke() to sweep the Sherwood LP's accrued Uniswap fees and compound them back into the locked position, fees never leave to a wallet.
function poke() // permissionless: compound Sherwood LP fees back into the floor
event Posted(uint128 sherwoodL, uint128 bountyL, uint128 ambushL)
event Poked(int24 tick, uint128 bountyL, uint128 ambushL, uint256 sherwoodFees0, uint256 sherwoodFees1)02 · Contracts & ABIEvents reference
These are everything the indexer consumes, enough to reconstruct the full state of the pad.
| Event | Emitter | Meaning |
|---|---|---|
| Launched | Factory | New coin: token, curve, pool, dev, opening buy |
| Bought | Router | A buy: ETH in, fee, tokens out |
| Sold | Router | A sell: tokens in, fee, ETH out |
| FeeSplit | Router | Exact fee routing per trade (platform/deferred/cut/dev/floor/burn) |
| Graduated | Curve | Graduation: raised WETH, the Bond address |
| Posted / Poked | Bond | Floor posted / fees compounded |
03 · IntegrateBuild a bot
Everything here is permissionless and public: no API key, no allow-list, no sign-up. If you can send a transaction, you can integrate. Three calls get you a working trade bot: watch launches, buy, sell.
// legacy overrides - spread into EVERY write (buy/sell/launch/graduate) async function legacy(provider){ const { gasPrice } = await provider.getFeeData(); return { type: 0, gasPrice }; } // 1) WATCH new launches - one event on the factory const factory = new ethers.Contract(FACTORY, [ "event Launched(address indexed token,address indexed curve,address indexed pool,address dev,uint256 devBought)", ], provider); factory.on("Launched", (token, curve, pool, dev) => { // ...decide whether to snipe it, inside the same block the dev opens }); // 2) BUY - native ETH in, no approval const value = ethers.parseEther("0.1"); const q = await router.buy.staticCall(token, 0n, { value }); await (await router.buy(token, q * 99n / 100n, { value, ...(await legacy(signer.provider)) })).wait(); // 3) SELL - one exact-amount approval, then sell await (await erc20.approve(ROUTER, amountIn, await legacy(signer.provider))).wait(); await (await router.sell(token, amountIn, minOutEth, await legacy(signer.provider))).wait();
Ideas that print: snipe bot (buy on Launched) · buy-alert / trending bot (poll the API → Telegram/X) · keeper (graduate() is permissionless, fire it when ready() flips) · copy-trade (mirror a wallet's Bought/Sold). Nothing to request, no rate limit on-chain, and every trade your bot routes still pays the coin's fee in-protocol, so the floor and the whole ecosystem grow with your volume. Bring the bots.
03 · IntegrateLaunch a coin
One transaction. Send ETH with the call to make the creator's opening buy (uncapped, excess is refunded), or send 0 for a clean launch. All snippets use ethers v6.
import { ethers } from "ethers"; const FACTORY = "0x8aa92d5297fEC45cbC7F16A32F4aed5D3AC58074"; const abi = [ "function launch((string name,string symbol,address dev,(uint16 buyBps,uint16 sellBps,uint16 walletBps,uint16 floorBps,uint16 burnBps,address projectWallet) tax) p) payable returns (address token,address curve,address pool)", ]; const signer = await new ethers.BrowserProvider(window.ethereum).getSigner(); const factory = new ethers.Contract(FACTORY, abi, signer); const me = await signer.getAddress(); const params = { name: "Sherwood", symbol: "WOOD", dev: me, tax: { buyBps: 100, // 1% buy → platform (min) sellBps: 100, // 1% sell → you, the creator (min) walletBps: 0, floorBps: 0, burnBps: 0, // split of any ABOVE-1% fee projectWallet: me, // where your sell fee lands }, }; // staticCall first to get addresses without spending gas, then send. const [token] = await factory.launch.staticCall(params, { value: 0n }); const tx = await factory.launch(params, { value: ethers.parseEther("0.02") }); // opening buy await tx.wait(); console.log("launched", token);
03 · IntegrateBuy & sell
const ROUTER = "0xA6BaAB820809C7fC8350311776627298f91F07eC"; const rAbi = [ "function buy(address token,uint256 minOut) payable returns (uint256)", "function sell(address token,uint256 amountIn,uint256 minOutEth) returns (uint256)", ]; const router = new ethers.Contract(ROUTER, rAbi, signer); // legacy() = { type:0, gasPrice } - REQUIRED on every write (no EIP-1559 on Robinhood Chain) async function legacy(p){ const { gasPrice } = await p.getFeeData(); return { type: 0, gasPrice }; } // BUY - native ETH in, no approval. Quote first, then apply slippage. const value = ethers.parseEther("0.1"); const quoted = await router.buy.staticCall(token, 0n, { value }); const minOut = quoted * 99n / 100n; // 1% slippage await (await router.buy(token, minOut, { value, ...(await legacy(signer.provider)) })).wait(); // SELL - one EXACT-amount approval to the router, then sell. const erc20 = new ethers.Contract(token, ["function approve(address,uint256) returns (bool)"], signer); await (await erc20.approve(ROUTER, amountIn, await legacy(signer.provider))).wait(); await (await router.sell(token, amountIn, minOutEth, await legacy(signer.provider))).wait();
03 · IntegrateRead curve state
The curve's ticks + the pool's current tick give you progress and market cap. (Or skip all of this and hit the indexer API, which precomputes it.)
const curve = new ethers.Contract(curveAddr, [ "function pool() view returns (address)", "function startTick() view returns (int24)", "function gradTick() view returns (int24)", "function graduated() view returns (bool)", ], provider); const [poolAddr, start, ceil] = await Promise.all([curve.pool(), curve.startTick(), curve.gradTick()]); const pool = new ethers.Contract(poolAddr, [ "function slot0() view returns (uint160 sqrtPriceX96,int24 tick,uint16,uint16,uint16,uint8,bool)", ], provider); const { tick } = await pool.slot0(); const span = Math.abs(Number(ceil) - Number(start)) || 1; const progress = Math.min(1, Math.abs(Number(tick) - Number(start)) / span); // 0 … 1
03 · IntegrateGraduate & dev controls
const curve = new ethers.Contract(curveAddr, [ "function ready() view returns (bool)", "function graduate()", ], signer); // ready() is true ONLY at the full ceiling (~4.2 ETH). Anyone can graduate once // ready() - this is the "Graduate" button / a keeper bot. No early path, no timeout. if (await curve.ready()) await (await curve.graduate()).wait(); // Creator only: collect your escrowed sell fees - or buy + burn with them. const router = new ethers.Contract(ROUTER, [ "function withdrawDev(address)", "function burnDev(address)", ], signer); await (await router.withdrawDev(token)).wait();
04 · EconomicsFee model
Two fee streams, both governed by the on-chain FeeConfig dial. The platform owner retunes the splits with a setter, with no redeploy. Curves and the router read the ratios live.
| Stream | Split (default) | Detail |
|---|---|---|
| LP fee, the in-protocol 1% | Platform 90% / Creator 10% | The Uniswap v3 pool's own 1% fee, swept by CurvePool.collectFees(); creator's cut is lpCreatorBps (owner cap 50%) |
| Swap-desk fee, the router's cut | Platform 45% / Creator 45% / Floor 10% | FeeConfig.swapSplit(); the three shares must sum to 100%. Floor deepens the coin's Bond |
| Graduation reward | Creator + Platform | 0.5 ETH each at the ceiling (capped at raise/4); the rest funds the floor |
| Sherwood LP fees | The floor | Compound back into the locked Bond via poke() |
04 · EconomicsGraduation: one ceiling, no shortcuts
Graduation happens at exactly one place: the full ceiling (~4.2 ETH raised, ~$34k mcap). A coin graduates only when buys carry the price all the way to gradTick: there is no early graduation, no creator override, and no timeout fallback. Below the ceiling the coin simply keeps trading on the curve, and sellers can always exit.
| Parameter | Meaning | Set by |
|---|---|---|
| startTick | Curve start (~$3.4k FDV) | Fixed at launch |
| gradTick | Ceiling, the ONLY graduation point (~4.2 ETH). Buys can't push past it | Fixed at launch |
| ready() | True only once the tick reaches gradTick | On-chain, permissionless |
On graduation the curve collects the raised WETH + unsold tokens, pays the creator 0.5 ETH and the platform 0.5 ETH (each capped at a quarter of the raise), and posts the rest as the Bond: the Sherwood full-range LP, the Bounty WETH floor, and the Ambush token wall.
05 · Build on itIndexer API
An optional read API (see /indexer in the repo) reads the events above into a database and serves a fast browse feed, trending/top sorting, search, per-coin trades and volume, so you don't fan out dozens of RPC calls per page. It's read-only and signs nothing; the pad falls back to direct-RPC when it isn't configured.
| Route | Returns |
|---|---|
| GET /health | { ok, head, cursor, coins, trades } |
| GET /api/stats | Totals: coins, graduated, 24h volume & trades |
| GET /api/coins | Browse feed, params below |
| GET /api/coin/:token | One coin, fully enriched (progress, mcap, volume) |
| GET /api/trades/:token | Recent trades (exact wei) |
# sort: new | trending | top | graduated filter: all | live | graduated GET /api/coins?sort=trending&filter=live&q=wood&limit=60 # each coin includes: { token, curve, pool, dev, name, symbol, launchTs, devBought, graduated, raisedWeth, bond, progress, mcapEth, lastPriceEth, # live snapshot - no chain read needed tradesAll, trades24h, volAllEth, vol24hEth, startTick, gradTick }
05 · Build on itSecurity model
- No proxies, no upgrades. The contracts are immutable. The platform owner (Ownable2Step) can only set the fee wallet for new launches, never touch a live coin, its curve, or the Bond.
- Floor-drain closed. Graduation refuses to post above the ceiling, the only unbacked price zone. Anywhere inside the curve, moving price up costs real WETH that joins the raise, so a manipulated graduation price is one the attacker paid for, and the floor sits below it.
- Conservation. Every wei of WETH and every token is accounted for across the lifecycle, verified to the wei by a 300-run fuzz and a random-graduation battery.
- Anti-snipe. The creator's opening buy runs atomically inside the launch tx; a CREATE2 salt with per-launch entropy blocks pre-init pool DoS.
- Fees in-protocol. The 1% is the Uniswap LP fee tier, not a side transfer, with no extra instruction ever attached to a user's transaction.