● Live on Robinhood Chain

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 “let it ride” 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.

01 · Start hereNetwork & addresses

KeyValue
ChainRobinhood Chain (Arbitrum Orbit L2, EVM)
Chain ID4663  (0x1237)
CurrencyETH (18 decimals)
Public RPChttps://robinhoodchain.blockscout.com/api/eth-rpc
Explorerhttps://robinhoodchain.blockscout.com
Per-tx gas cap16,777,216 (2²⁴) — relevant if you batch calls

Contract addresses (live)

ContractAddressRole
CurvePadFactory0x44855d49E73Ad103Df51871A072FEe8709E6A2d6One-call launch entrypoint
PadRouter0xAEFE708e04D3E2e9609e6bC987903b31818C2a46The swap desk — every buy/sell goes through it
WETH0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73Canonical wrapped ETH
UniswapV3Factory0x1f7d7550b1b028f7571e69a784071f0205fd2efaThe 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:

ContractOwns
CurvePadFactoryDeploys the token + curve + pool in one tx, registers the coin with the router, runs the anti-snipe opening buy.
CurvePoolThe bonding curve — a single-sided v3 position spanning [startTick → gradTick]. Owns graduation and the “let it ride” logic.
PadRouterThe only trade path. Applies the 1% fee in-protocol, splits it to escrows, exposes dev fee controls.
BondProtocol-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 (capped at 2% of supply), executed atomically before public trading opens.

Solidity ABI · human-readable (ethers)
// 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)
Fee caps (enforced on-chain)Each side (buyBps/sellBps) is 1%–4% (100–400 bps). The baseline 1% is mandatory. The opening dev buy is capped at 2% of supply (200 bps). Total supply is fixed at 1,000,000,000.

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.

Solidity ABI · human-readable (ethers)
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 and the graduation window; call graduate() (permissionless) to post the Bond, or setGradTarget() (creator-only) to move the auto-graduate price.

Solidity ABI · human-readable (ethers)
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)       // eligible to graduate right now
function seedTime() view returns (uint64)

// geometry — ticks along the curve (price rises left→right)
function startTick() view returns (int24)      // curve start (~$4k FDV)
function minGradTick() view returns (int24)    // earliest graduation (~$30k)
function gradTarget() view returns (int24)     // auto-graduate price (dev-settable)
function gradTick() view returns (int24)       // ceiling (~$76k)

function setGradTarget(int24 targetTick)   // creator only, within [min, ceiling]
function graduate()                        // permissionless once ready()

event Seeded(int24 curveLo, int24 curveHi, uint128 liquidity)
event GradTargetSet(int24 targetTick)
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.

Solidity ABI · human-readable (ethers)
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.

EventEmitterMeaning
LaunchedFactoryNew coin: token, curve, pool, dev, opening buy
BoughtRouterA buy: ETH in, fee, tokens out
SoldRouterA sell: tokens in, fee, ETH out
FeeSplitRouterExact fee routing per trade (platform/deferred/cut/dev/floor/burn)
GradTargetSetCurveCreator moved the auto-graduate price
GraduatedCurveGraduation: raised WETH, the Bond address
Posted / PokedBondFloor 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.

JavaScript · ethers v6
// 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 })).wait();

// 3) SELL — one exact-amount approval, then sell
await (await erc20.approve(ROUTER, amountIn)).wait();
await (await router.sell(token, amountIn, minOutEth)).wait();
Skip the RPC crawlFor discovery, don't poll the chain — hit the indexer API: GET /api/coins?sort=new for a snipe feed, ?sort=trending for what's hot, /api/trades/{token} for a coin's flow. Every coin comes back with progress, mcap, price and 24h volume — no per-coin reads.

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 (≤2%), or send 0 for a clean launch. All snippets use ethers v6.

JavaScript · ethers v6
import { ethers } from "ethers";

const FACTORY = "0x44855d49E73Ad103Df51871A072FEe8709E6A2d6";
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);
Opening buy = anti-snipe, not a feeThe ETH you send is your own buy, executed inside the launch tx before anyone else can trade — it isn't a platform charge. Capped at 2% of supply.

03 · IntegrateBuy & sell

JavaScript · ethers v6
const ROUTER = "0xAEFE708e04D3E2e9609e6bC987903b31818C2a46";
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);

// BUY — native ETH in, no approval. Quote first, then apply slippage.
const quoted = await router.buy.staticCall(token, 0n, { value: ethers.parseEther("0.1") });
const minOut = quoted * 99n / 100n; // 1% slippage
await (await router.buy(token, minOut, { value: ethers.parseEther("0.1") })).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)).wait();
await (await router.sell(token, amountIn, minOutEth)).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.)

JavaScript · ethers v6
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

JavaScript · ethers v6
const curve = new ethers.Contract(curveAddr, [
  "function ready() view returns (bool)",
  "function graduate()",
  "function setGradTarget(int24 targetTick)",
], signer);

// Anyone can graduate once ready() — this is the "Graduate" button / a keeper bot.
if (await curve.ready()) await (await curve.graduate()).wait();

// Creator only: move the auto-graduate price. Lower = graduate sooner;
// higher = ride longer for a bigger raise + thicker floor.
await (await curve.setGradTarget(targetTick)).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

Every coin pays a mandatory 1% per side. A creator may set a side higher (up to 4%); the amount above 1% is the “raised” fee and splits 25% platform / 75% project.

FlowGoes toDetail
Buy 1% basePlatform0.9% immediately, 0.1% released at graduation
Sell 1% baseCreatorEscrowed; collect to wallet or buy+burn
Above-1% (raised)25% platform / 75% projectProject 75% splits by walletBps/floorBps/burnBps
Graduation rewardCreator + Platform0.5 ETH each at graduation; the rest funds the floor
Sherwood LP feesThe floorCompound back into the locked Bond via poke()
Creator income1% sell tax + a 0.5 ETH graduation reward + any project share of raised tax. Every share is escrowed and paid by separate permissionless flushers, so a trade can never revert on a payout. Accounting is exact to the wei.

04 · EconomicsGraduation — “let it ride”

Graduation is a window, not a line. It becomes eligible at the minimum (~$30k mcap) and can fire anywhere up to the ceiling (~$76k). The longer a coin rides, the bigger the raise and the thicker the floor.

ParameterMeaningSet by
minGradTickEarliest graduation is allowed (~$30k)Fixed at launch
gradTargetAuto-graduate price. Defaults 40% up the range (~$45k)Creator (setGradTarget)
gradTickCeiling (~$76k). Buys can't push past itFixed at launch
TimeoutAfter 7 days, anyone may graduate at the minimumPermissionless fallback

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.

RouteReturns
GET /health{ ok, head, cursor, coins, trades }
GET /api/statsTotals: coins, graduated, 24h volume & trades
GET /api/coinsBrowse feed — params below
GET /api/coin/:tokenOne coin, fully enriched (progress, mcap, volume)
GET /api/trades/:tokenRecent trades (exact wei)
HTTP
# 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, minGradTick, gradTick, gradTarget }
Built for scaleThe feed is served from precomputed snapshots (progress/mcap refreshed whenever a coin trades), so a page that lists thousands of live coins costs one request and zero per-coin RPC. Responses are cacheable (max-age=5) — put a CDN in front and a launch-day crowd hits cache, not the database.

05 · Build on itSecurity model

AuditThree internal audit passes (manual, deep pre-production, and a dedicated adversarial pass) plus a live mainnet lifecycle validation. Findings and resolutions live in launchpad/AUDIT.md; contract source in launchpad/contracts/.