JETPAD docs X Open app
Robinhood Chain · 4663

Everything about JetPad, in one place

How a launch works, where the price comes from, who gets paid, and every address and event you need to index it yourself.

Overview

JetPad is a place to launch and trade tokens on Robinhood Chain. You can browse launches, open any token to see its details, and trade straight from your wallet.

JetPad never holds your funds. Every launch and every trade is a transaction your own wallet asks you to approve, sent to a contract that cannot hold a balance between transactions.

Key facts

  • Names and symbols can be copied. Always check the token address.
  • Prices come from each token's own Uniswap v4 pool, from its first block.
  • Every token has a fixed supply of 1,000,000,000 and 18 decimals.
  • Pools hold native ETH. Nothing is ever wrapped.
  • Launches can be volatile, illiquid, or lose all value.

What JetPad does not have

There is no bonding-curve phase, no migration, and no graduation. Most launchpads sell from an off-DEX curve first and move the liquidity to a real pool later; until that moment the token has no pool, so scanners cannot read it and aggregators cannot list it.

A JetPad coin skips that stage entirely. The pool is real, the liquidity is burned, and the token is tradable in the same transaction that creates it. There is no later event to wait for, and no step at which anything moves.

How launches work

Creating a launch runs one atomic transaction. It deploys the ERC-20, opens its Uniswap v4 pool against native ETH, deposits 100% of the supply as a single-sided position, mints the position NFT directly to 0x…dEaD, arms the 1% fee, and executes the creator's first buy. If any part fails, none of it happened.

01
Create

Token, pool and liquidity in a single transaction. The position NFT is minted straight to the burn address — it is never held, then burned; it is never held at all.

02
Trade

Buys and sells run against native ETH in that same pool, from the first block, and move the price. Nothing migrates, ever.

03
Earn

Every swap pays 1% in ETH. The creator's share accrues to their address for as long as the coin trades, and can be claimed at any time.

A single-sided position is a bonding curve

This is not an analogy. A liquidity position L over a price range [a, b] behaves exactly like a constant product with virtual reserves:

Identity
(x + L/√b) · (y + L·√a) = L²        for every price P in [a, b]

virtual ETH reserve    V_e = L / √b
virtual token reserve  V_t = L · √a
constant               k   = L²

So the curve everyone expects is there. JetPad just expresses it in Uniswap's own representation instead of a bespoke contract — which is precisely why there is nothing left to migrate afterwards, and why the pool is readable by every scanner and aggregator from the start.

The pool opens at the top of the range holding only tokens and zero ETH. Buys push the price down the range in Uniswap's orientation, which in human terms means the price in ETH per token goes up. The ETH that buyers deposit is what pays sellers — which is what makes a coin sellable from the very first trade, with no condition and nothing to unlock.

The creator's first buy

Every launch includes a buy by the creator, in the same transaction, at the floor price. It is required, and the minimum is 0.01 ETH.

Why there is a minimum

The pool opens with 100% tokens and zero ETH. The creator's buy is the only ETH in it at block one. A honeypot detector buys, then tries to sell everything it just bought — and a pool too shallow to pay that sell back reverts, which the scanner correctly reports as “cannot be sold”.

0.01 ETH is the floor measured as sufficient on this chain, not an estimate. Below it, coins were flagged; at it, they are clean.

This is not a fee

The creator buys their own tokens and can sell them back at any time. Measured round trip: 0.0105 ETH in, 0.01029 ETH out. The real cost is the 1% hook fee each way plus gas — roughly 0.0002 ETH. The rest is committed, not spent.

The cap on the first buy

The atomic first buy cannot exceed 50% of the supply (MAX_DEV_BUY_BPS = 5000). That limit is a constant in the bytecode — no admin can raise it, which is what makes it a guarantee rather than a policy.

Read this cap correctly

It bounds the creator's privilege, not their holdings. It applies to the one window where they buy with no possible competition, because the pool did not exist a moment earlier. Once createCoin returns, the creator can buy more like anyone else — at the market price, in competition with everyone, paying the 1% each time.

Never treat it as a guarantee about how the supply is distributed. Check the holders.

The opening market cap is deliberately low, and you should size that before you buy: at the STANDARD tier it is about 2.47 ETH, so 1 ETH buys roughly 29% of the supply. Both the ETH spent and the tokens received by the creator are published in the CoinCreated event, and shown on every coin's page.

Trading and pricing

Every token trades against native ETH in its own Uniswap v4 pool. The price you see is the live pool price and it moves with every trade. What you actually receive can differ from the quote; slippage is how much of that movement you agree to accept.

Price

The current pool price of one token, in ETH.

Market cap

Price multiplied by the total supply.

FDV

Identical to market cap here: the supply is fixed and fully minted at launch.

Price impact

How far your own trade moves the pool.

Slippage

The worst execution you accept before the transaction reverts.

Liquidity

What the position holds around the current price — it starts as tokens and becomes ETH as people buy.

Trades are routed through JetstreamRouter, a contract with no owner, no proxy, no pause, no sweep function, no Permit2 dependency, and no ability to hold a balance between transactions. The JetPad interface refuses to send anything to any other target.

Launch tiers

A tier sets the price range of the launch position, and therefore the opening market cap. All three tiers share the same range width (55,800 ticks), so all three have the same ceiling — a ×265 move from the floor to the top of the range. Only the scale in ETH changes.

TierTick rangeOpening market capCost to buy the whole supplyMultiple
0 · LOW152,200 → 208,0000.92710 ETH15.0920 ETH×265.00
1 · STANDARD142,400 → 198,2002.47010 ETH40.2101 ETH×265.00
2 · PREMIUM133,400 → 189,2006.07518 ETH98.8963 ETH×265.00

These are the values actually reached, re-derived from the rounded ticks — never the requested bounds. Uniswap only accepts ticks on a 200 grid, so the grid moves the numbers by +0.5% to −1.1%, and the honest figure to publish is the one on chain.

The buyout cost is what lands in the pool, so it is net of the hook fee: a buyer actually pays cost / (1 − 0.01).

What the interface uses

The JetPad create form launches every coin at STANDARD. The other two tiers exist on the contract and are readable through launchParams(tier) and launchEconomics(tier), but the form does not currently expose the choice.

Fees

There is one fee: 1% of every swap, taken by JetstreamHook on the ETH leg. It is always paid in ETH, never in the memecoin, from the very first trade.

The pool's own LP fee is zero. The hook is the only source of fees in the system, which is what lets the liquidity position be burned and still produce revenue — the fee belongs to the swap, not to whoever holds the liquidity.

How the 1% is split

The split is frozen per coin, at launch

feeBps, devBps and buybackBps are written into configOf[poolId] when the pool is registered, and read from there forever after. The owner cannot change the fee or the split of a coin that already exists.

Only the destination wallets are read live, so that a compromised address can be replaced. The shares themselves cannot be.

The fee rate is capped at 300 bps by a constant in both the factory and the hook. It is 100 bps today. There is no creation fee: creationFee is 0.

Creator rewards

Fees accumulate per pool as pendingEth[poolId], held as ERC-6909 claims on the Uniswap PoolManager. Turning them into real ETH takes two permissionless steps:

Claiming
// 1. Split what has accrued. Anyone can call this, for any number of pools at once.
//    The proceeds are credited to the beneficiaries, never to the caller.
hook.harvest(bytes32[] poolIds)

// 2. Withdraw your own balance. address(0) means native ETH.
hook.claim(0x0000000000000000000000000000000000000000)

Both are available from the profile panel in the JetPad interface, which shows each of your coins, its market cap, and what it currently has waiting.

The creator role can be handed over with a two-step transfer — transferCreator(poolId, to) then acceptCreator(poolId) from the new address. It moves the fee stream and nothing else: it grants no power over the liquidity, which is burned, or over trading.

What is guaranteed

These are properties of deployed bytecode, each one verifiable by anyone without trusting JetPad.

PropertyHow to check it
Liquidity is burned The position NFT is minted directly to 0x…dEaD. Call ownerOf(positionTokenId) on the Uniswap PositionManager.
The token has no owner owner() is a pure function returning the zero address. There is no storage behind it, and no transferOwnership.
No mint after deployment The entire supply is minted once, in the constructor. There is no mint path.
No transfer can be blocked _update is not overridden. No pause, no blacklist, no cooldown, no max-wallet — nothing that could make a transfer fail beyond ERC-20's own rules.
Positions stay withdrawable The hook holds no remove-liquidity permission bits. Even if its swap path ever broke, every position could still be withdrawn.
Pausing cannot trap funds The factory's pause freezes createCoin only. Swaps live in the PoolManager and fees in the hook; neither consults it.
Fees are pull, never push Nothing is ever pushed to a beneficiary. Balances are claimed by their owner.

Risk disclosures

Tokens launched through JetPad are user-created and experimental. Before signing, review the token address, the creator, the liquidity, the holder concentration and the transaction preview.

  • Prices can move quickly and liquidity can be thin.
  • Similar names and images can represent completely unrelated tokens.
  • A creator's first buy can be as large as half the supply. Check who holds what.
  • Smart contracts, wallets, RPCs and indexers can fail.
  • Displayed values are estimates, not execution guarantees.
  • The contracts have not been reviewed by an external auditor.

JetPad is an interface. It is not investment advice, and it is not a statement about any token's quality.

Network

A small, verifiable integration surface. Everything reads off the contracts — index the factory and the pool events and you have a trust-minimised source of truth that does not depend on JetPad being up.

PropertyValue
NetworkRobinhood Chain (Arbitrum Nitro)
Chain ID4663 · 0x1237
Native assetETH
Public RPChttps://rpc.mainnet.chain.robinhood.com
Explorerrobinhoodchain.blockscout.com
Block time~0.10 s
DEXUniswap v4, native ETH, custom hook
Pool LP fee0 — the hook is the only fee
Tick spacing200
Supply1,000,000,000 (1e9 × 1e18)
Creation fee0
Minimum creator buy0.01 ETH
Two things that will bite an indexer here
  • block.number returns the L1 block number and only advances every ~12 s. Never use it as a clock. block.timestamp and ArbSys.arbBlockNumber() track L2.
  • eth_getLogs errors above its cap rather than truncating — good — but the observed cap does not match the announced one. Do not hardcode a range: split adaptively, driven by the error.

Contracts

Deployed addresses on Robinhood Chain. Contracts are immutable: a new version ships as new addresses, listed here.

JetstreamFactory start block 23,628,017
0x4c0cdfB2cb5D38F58e20152C7B9dCFb39019A52f
JetstreamHook permission bits 0x08CC
0x4b16B138089673cC37a85E2aafe69Dd5265208Cc
JetstreamRouter ownerless, no proxy
0x9aA268b875Aa1b1a23f229Ac93395B9dA4Ee47e5
Uniswap v4 PoolManager holds every pool
0x8366a39CC670B4001A1121B8F6A443A643e40951
Uniswap v4 PositionManager holds the burn proof
0x58daec3116aae6D93017bAAea7749052E8a04fA7
Burn address every position NFT
0x000000000000000000000000000000000000dEaD
The factory and the hook can never be replaced separately

The hook's factory is immutable and its address is CREATE2-mined to carry exactly the permission bits 0x08CC in its low 14 bits. Changing either contract changes the mined address, so they are always deployed as a pair. If you see one of them change, expect the other to have changed too.

Hostile addresses

The canonical Uniswap addresses are traps on this chain

At the addresses Uniswap uses on Ethereum and every other chain, this chain hosts an unrelated contract whose fallback forwards msg.value to a third party. They are not a stale deployment to be corrected — sending ETH to them is a loss of funds.

AddressWhat it is elsewhere
0x1F98431c…F984UniswapV3Factory — drainer here
0xC36442b4…FE88NonfungiblePositionManager — drainer here
0xE592427A…1564SwapRouter — drainer here
0x61fFE014…B21eQuoterV2 — drainer here
0x6fF5693b…9b43Real UniversalRouter bytecode, every immutable dangling
0x88767899…0904UniversalRouter with a proven bytecode modification

JetPad refuses these addresses in two independent places — in the browser before signing, and in the API before it will name any call target at all. Duplicating that check is deliberate: this is the one class of mistake that cannot be undone.

Onchain events

Index CoinCreated on the factory, then the PoolManager's Swap events filtered by each poolId. Onchain events are the authoritative source of truth, and no eth_call is needed: CoinCreated carries the entire launch position.

JetstreamFactory
event CoinCreated(
  address indexed token,
  address indexed creator,
  bytes32 indexed poolId,
  string  name,
  string  symbol,
  string  tokenURI,        // IPFS CID
  uint256 totalSupply,     // always 1e27
  uint256 positionTokenId, // NFT minted to 0x…dEaD — the burn proof
  uint160 sqrtPriceX96,    // opening price, exactly sqrt(tickUpper)
  uint128 liquidity,
  int24   tickLower,
  int24   tickUpper,
  uint8   tier,            // 0 LOW · 1 STANDARD · 2 PREMIUM
  uint16  feeBps,          // frozen for this pool (100 = 1%)
  uint256 devBuyEth,       // ETH the creator's first buy actually spent
  uint256 devBuyTokens,    // tokens they received — display this
  uint16  implVersion      // 3 = single-sided launch
);

// topic0
0xef85cf514fdefb3937035e5e5f9200299d6354dae086a76b9271b5e363ebab07
JetstreamHook
// Written once per coin, by the factory, during creation.
event PoolRegistered(bytes32 indexed poolId, address indexed token, address indexed creator, uint16 feeBps);

// Emitted on EVERY swap. This is the coin's revenue, with no state read at all.
// `takenBeforeSwap` says which leg paid; the amount is always in wei of ETH.
event HookFeeAccrued(bytes32 indexed poolId, uint256 amount, bool takenBeforeSwap);

// A treasury movement, not new revenue. Do not double-count it against the above.
event HookFeesHarvested(bytes32 indexed poolId, uint256 amount);

event CreatorTransferStarted(bytes32 indexed poolId, address indexed from, address indexed to);
event CreatorTransferred(bytes32 indexed poolId, address indexed from, address indexed to);

// role: 0 = DEV · 1 = BUYBACK · 2 = PLATFORM. asset(0) = native ETH.
event FeesAccrued(address indexed account, address indexed asset, uint256 amount, uint8 role);
event FeesClaimed(address indexed account, address indexed asset, uint256 amount);

The PoolKey, and deriving the poolId

A v4 pool has no address of its own. It is identified by the hash of its key, and every JetPad pool has the same shape:

FieldValue
currency00x0000000000000000000000000000000000000000 — native ETH, always sorts first
currency1the coin, always
fee0
tickSpacing200
hooksthe JetstreamHook address
Do not simulate against a standard fee tier

fee is 0, not 3000 or 10000. Quoting or simulating a JetPad pool with a standard tier reverts PoolNotInitialized() — which is a tooling mistake, and says nothing whatsoever about the coin.

Reading launches with viem
import { createPublicClient, http, parseAbiItem } from "viem";

const client = createPublicClient({
  chain: {
    id: 4663,
    name: "Robinhood Chain",
    nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
    rpcUrls: { default: { http: ["https://rpc.mainnet.chain.robinhood.com"] } },
  },
  transport: http(),
});

const launches = await client.getLogs({
  address: "0x4c0cdfB2cb5D38F58e20152C7B9dCFb39019A52f",
  event: parseAbiItem(
    "event CoinCreated(address indexed token, address indexed creator, bytes32 indexed poolId, string name, string symbol, string tokenURI, uint256 totalSupply, uint256 positionTokenId, uint160 sqrtPriceX96, uint128 liquidity, int24 tickLower, int24 tickUpper, uint8 tier, uint16 feeBps, uint256 devBuyEth, uint256 devBuyTokens, uint16 implVersion)",
  ),
  fromBlock: 23628017n,   // the factory's first block — earlier is wasted work
  toBlock: "latest",
});
There is no terminal event

Nothing replaces the Migrated event other launchpads emit — a JetPad coin is in its final state from CoinCreated onward. An indexer waiting for a transition should be simplified, not adapted. Deduplicate on (txHash, logIndex).

Reading token state

Every launch token is self-describing on chain, and the factory answers everything else about the launch.

The token
function name()        view returns (string)
function symbol()      view returns (string)
function decimals()    view returns (uint8)     // 18
function totalSupply() view returns (uint256)   // 1e27, fixed
function tokenURI()    view returns (string)    // IPFS CID: image, description, links
function factory()     view returns (address)
function owner()       pure returns (address)   // always 0x0 — a constant, not storage

// ⚠️ `curve()` is a legacy name kept so an external ABI does not break. It returns the
//    factory, which received the supply and put all of it in the pool in the same
//    transaction. It confers no power of any kind.
function curve()       view returns (address)
The factory
poolIdOf(address token)            returns (bytes32)   // the pool's identity
poolKeyOf(address token)           returns (PoolKey)
positionTokenIdOf(address token)   returns (uint256)   // 0 = unknown to this factory
launchParams(uint8 tier)            returns (tickLower, tickUpper, sqrtPriceX96Init, liquidity)
launchEconomics(uint8 tier)         returns (startingMarketCapWei, fullBuyoutCostWei, finalMarketCapWei)
coinCount()                          returns (uint256)
feeBps() devBps() buybackBps()      // the CURRENT defaults for NEW coins
The hook
configOf(bytes32 poolId)   returns (set, creator, feeBps, devBps, buybackBps)
feeBpsOf(bytes32 poolId)   returns (uint16)    // 0 = not a JetPad pool
creatorOf(bytes32 poolId)  returns (address)
pendingEth(bytes32 poolId) returns (uint256)   // accrued, not yet harvested

// selectors, if you are building calldata by hand
// pendingEth(bytes32)  0x4943253a
// harvest(bytes32[])   0x13df2c7a
// devBps()             0x78b2c179

To verify the burn — the one check worth doing on any coin — take positionTokenId from CoinCreated and call ownerOf(positionTokenId) on the Uniswap PositionManager. It returns 0x…dEaD, and it does so from the coin's very first block.

Pricing

The launch event carries enough to rebuild the whole curve off chain, with no RPC call. Prices after that come from the PoolManager's Swap events on the coin's poolId.

From the launch event
// currency0 is native ETH, so Uniswap's P is TOKENS per ETH.
// Human price (ETH per token) is 1/P — it goes UP as people buy.

ratio          = sqrtPriceX96 / 2**96
tokensPerEth   = ratio * ratio
ethPerToken    = 1 / tokensPerEth
marketCapWei   = totalSupply / tokensPerEth

// The equivalent virtual reserves, if you prefer curve terms:
sqrtA          = sqrtPriceX96AtTick(tickLower)
sqrtB          = sqrtPriceX96                    // opening price IS the upper bound
virtualEthWei  = liquidity / sqrtB
virtualTokens  = liquidity * sqrtA
k              = liquidity ** 2

// ETH needed to buy the entire supply, net of the 1% hook fee:
fullBuyoutWei  = liquidity * (1/sqrtA - 1/sqrtB)
One trap in that arithmetic

k = V_e × (S + V_t), not V_e × V_t. The y in the identity is the position's live balance — zero at launch, the full supply once everything has been sold — not a countdown from the supply. Getting this wrong is off by a factor of about 16.3 at the current calibration.

For USD figures, multiply by any ETH/USD source. The JetPad interface uses a spot feed and applies it to the ETH-denominated numbers; it never derives a USD price on chain.

Public API

A read API sits in front of the indexer for convenience — charts, search, quotes. It is a convenience layer over the chain, never an authority: everything it returns is derived from the events above, and anything that matters should be verified against them.

Base URL
https://api-production-ecec.up.railway.app
EndpointWhat it returns
GET /coinsThe listing. sort, limit, q, creator, status.
GET /coins/:addressOne coin: metadata, pool state, market cap, last trade.
GET /coins/:address/tradesTrade history, newest first.
GET /coins/:address/candlesOHLCV. Intervals down to 1s — the chain produces ten blocks a second.
GET /quote/:addressA priced buy or sell, plus ready-to-sign calldata and its target.
GET /quote/:address/stateLive pool state behind a quote.
GET /fees/:devAddressWhat a creator has accrued and can claim.
GET /launch/paramsTier calibration and the current minimum creator buy.
POST /launch/calldataEncoded createCoin calldata.
POST /metadataPins an image and its metadata to IPFS, returns the CID.
GET /healthDatabase, cache, pinning and indexer lag.

A WebSocket on the same host pushes new coins, trades and candle updates as they are indexed. The interface uses it instead of polling, because at 100 ms blocks polling is always behind.

Verify the quote before you sign it

/quote returns a call target and calldata. The API checks that the PoolKey it is about to encode hashes to the coin's own poolId before naming any address at all, and the JetPad browser client independently re-checks that the target is not a known decoy, that the approval spender is that same target, and that the calldata decodes to the numbers on screen. If you build your own client, do the same.

Support

If you are indexing launches, deriving prices, wiring trades or verifying onchain state, reach out and we will help you get it right.

@Jetstreamtrade on X

Versioning

Deployed contracts are immutable. New versions ship as new factory and hook addresses, listed under Contracts. implVersion in CoinCreated tells you which launch mechanism produced a given coin — 3 is the single-sided launch described here.

Terms and attribution

Onchain data is public and free to read. You are responsible for what you do with it. JetPad is provided as is, without warranties, and we are not liable for losses arising from integrations, interfaces, RPCs or indexers.

  • Do not present third-party services as operated by JetPad.
  • Do not use the JetPad name or marks in a way that misleads users.
  • Availability of the interface and of public infrastructure is not guaranteed.