RIFF documentation
Part I explains the protocol: how a launch works, how trading and fees work, and what protects a fresh token in its first blocks. Part II is a contract-first integration surface for anyone building against RIFF directly: network details, contract addresses, onchain events, and read examples in viem.
1. Overview
RIFF is a permissionless memecoin launchpad on Robinhood Chain. Anyone can launch a token in a single transaction: the token is deployed, its liquidity position is opened and locked, and trading can begin immediately in the same pool for the life of the token.
RIFF has no bonding curve and no migration step. There is no protocol buyback or burn mechanism, and no separate governance token. The one governance feature RIFF does ship is a creator-protected community takeover (CTO) process for the fee payout wallet, described in section 7.
2. Anatomy of a launch
A launch is a single atomic transaction. In one call the factory deploys the token, opens a single-sided, locked Uniswap V3 position for it, charges the launch fee, and (optionally) executes the creator's dev-buy from any leftover transaction value, all in one block.
- Fixed supply: 1,000,000,000 tokens, minted once at launch.
- Pool: 1% fee tier, paired against WETH.
- Liquidity is locked from launch: there is no bonding curve and no migration event.
- Launch fee: 0.0005 ETH, paid to the protocol.
3. Launch protection
Every launch opens with a short anti-snipe window, measured in blocks rather than time, so it applies evenly regardless of network conditions.
- The window lasts 2 blocks from launch.
- On the launch block itself, only the creator's atomic dev-buy can buy: no other buyer can get in before the creator.
- For the rest of the window, each wallet can hold at most 5% of supply and buy at most 5.5% of supply in total.
- The creator's dev-buy is itself capped at 5% of supply.
- Sells and wallet-to-wallet transfers are never restricted, at any point.
- All limits end automatically once the window closes; trading is unrestricted after that.
4. Trading and pricing
Trading is market-only: every trade goes through the token's Uniswap V3 pool at the 1% fee tier. There is no separate launchpad order book and no off-chain matching. The price you see is the pool's live price, read directly from its state.
| Term | Meaning |
|---|---|
| Price | The current price of one token in ETH, read from the pool's live state (slot0). |
| Market cap | Price multiplied by the fixed total supply. |
| FDV | Fully diluted value. Since supply is fixed, FDV equals market cap unless tokens have been burned. |
| Price impact | How much a trade moves the pool price; larger trades move it more. |
| Slippage | The maximum price movement a trader will accept before a trade reverts. |
| Liquidity | The ETH and token value available in the pool for trading. |
5. Graduation
A token graduates when the paired WETH principal in its pool reaches 4.2 ETH. Graduation is a one-way milestone: once reached, it stays reached. It does not change how the token trades. There is no migration; trading continues in the same pool before and after graduation. Graduation is a size milestone, not a quality signal.
6. Fees
Every trade pays a 1% fee. The split between the creator and the protocol is snapshotted per token at launch and never changes for that token afterward.
- Launch config: 80% to the creator, 20% to the protocol.
- The protocol's share is capped at 50% for any token.
- Creators can claim accrued fees from the RIFF interface at any time.
- Unclaimed fees may be auto-claimed and routed to the creator's payout wallet.
7. Governed community takeover (CTO)
If a creator disappears, the fee payout wallet for their token can be reassigned through a governed, on-chain process rather than an off-chain form. This is a differentiator versus other launchpads.
- The protocol owner proposes a new payout wallet.
- A 14-day on-chain timelock begins, during which the current creator can veto at any time.
- After the timelock, the proposal can be executed, moving the payout wallet.
- A CTO can never route the creator's fee share to the protocol, and it never changes the fee split itself: only the payout wallet moves.
- The creator can veto by explicitly cancelling the proposal, or simply by acting (any call that sets their own fee redirect cancels a pending proposal automatically).
8. Editable metadata and burns
Every RIFF token is self-describing on-chain: its name, symbol, logo, description, and social links are readable directly from the token contract, without depending on any off-chain database.
- The creator (only) can edit a token's social links after launch.
- Burns are simply transfers to the zero address. There is no separate protocol burn mechanism. The indexer counts burns per token from these transfers.
9. Risk disclosures
- Tokens on RIFF are user-created and experimental. Anyone can launch anything.
- Always check the token address you are interacting with.
- Prices can move fast and liquidity can be thin, especially for small or new tokens.
- Values shown in the interface (price, market cap, FDV) are estimates.
- RIFF is an interface to public, permissionless smart contracts. It is not investment advice.
10. Network
| Field | Value |
|---|---|
| Network | Robinhood Chain |
| Chain ID | 4663 |
| Native asset | ETH |
| Public RPC | https://rpc.mainnet.chain.robinhood.com |
| Explorer | robinhoodchain.blockscout.com |
| Pool fee | 10000 (1%) |
| Launch fee | 0.0005 ETH |
| Supply | 1,000,000,000 (1e9), fixed per token |
11. Contracts
The deployed RIFF contracts, plus the shared Uniswap infrastructure on Robinhood Chain:
| Contract | Address |
|---|---|
| WETH | 0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73 |
| Position manager | 0x73991a25C818Bf1f1128dEAaB1492D45638DE0D3 |
| Swap router | 0xCaf681a66D020601342297493863E78C959E5cb2 |
| RIFF factory | 0x059c45DB0fca09aACbe0de62f396512792ef6BaE |
| RIFF locker | 0x2f59694e9220e138344a13B1432056a68F7D165F |
12. Onchain events
To index RIFF activity, watch the factory's TokenLaunched event, register
each pool it announces, and index that pool's Swap events for trades.
TokenLaunched(address,address,address,address,uint256,uint256) topic0: 0x8d4aad4953d0ca700d468f3753aa14432d1b35b43ec6409f051fb6aa43a89607 FeesClaimed(address,address,address,address,uint256,uint256,uint256,uint256) topic0: 0x1547f2bd1a244399782ebde22047e2ede698ecdc4d6c7d4b3c4e2435f1e47f7a CtoProposed(address,address,uint64) topic0: 0x0c571ebfe82bccfab5a8bf9c83f44a9b169997f206310d489ade0ff794ebcc41 CtoExecuted(address,address) topic0: 0x66efaf5c3bbaa56182b3d306b97344fa75d2ac784eae0be617bd07bf8dea55b7
import { createPublicClient, http, parseAbiItem } from "viem";
const rhChain = {
id: 4663,
name: "Robinhood Chain",
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
rpcUrls: { default: { http: ["https://rpc.mainnet.chain.robinhood.com"] } },
};
const client = createPublicClient({ chain: rhChain, transport: http() });
// factory address is published at launch.
const launches = await client.getLogs({
address: factory,
event: parseAbiItem(
"event TokenLaunched(address indexed token, address indexed deployer, address pairedToken, address pool, uint256 positionId, uint256 supply)"
),
fromBlock: "earliest",
toBlock: "latest",
});
eth_getLogs ranges. Backfill in bounded block chunks starting from the factory's
deployment block.13. Reading token state
Every RIFF token is self-describing on-chain: name, symbol, logo, description, socials, and the restriction window can all be read directly from the token contract.
import { parseAbi } from "viem";
// The launch token is self-describing on-chain.
const tokenAbi = parseAbi([
"function name() view returns (string)",
"function symbol() view returns (string)",
"function decimals() view returns (uint8)",
"function totalSupply() view returns (uint256)",
"function logo() view returns (string)",
"function description() view returns (string)",
"function creator() view returns (address)",
"function liquidityPool() view returns (address)",
"function socials() view returns (string twitter, string telegram, string website, string discord, string farcaster)",
"function restrictionEndBlock() view returns (uint256)",
]);
const [name, symbol, pool, creator] = await Promise.all([
client.readContract({ address: token, abi: tokenAbi, functionName: "name" }),
client.readContract({ address: token, abi: tokenAbi, functionName: "symbol" }),
client.readContract({ address: token, abi: tokenAbi, functionName: "liquidityPool" }),
client.readContract({ address: token, abi: tokenAbi, functionName: "creator" }),
]);
const factoryAbi = parseAbi([
"function getLaunchedToken(address token) view returns ((bool exists, address token, address deployer, address pairedToken, address positionManager, uint256 positionId) launched)",
]);
const { launched } = await client.readContract({
address: factory, abi: factoryAbi, functionName: "getLaunchedToken", args: [token],
});
// launched.deployer is the creator payout default; launched.pairedToken is WETH.
14. Pricing and graduation
Price is read directly from the pool's slot0. Token and WETH both use 18
decimals, so no decimal scaling is needed; the only adjustment is ordering token0 versus
token1.
import { parseAbiItem } from "viem";
const [sqrtPriceX96] = await client.readContract({
address: pool,
abi: [parseAbiItem(
"function slot0() view returns (uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked)"
)],
functionName: "slot0",
});
// Token and WETH both use 18 decimals, so no decimal scaling is needed.
const isToken0 = token.toLowerCase() < pairedToken.toLowerCase();
const ratio = Number(sqrtPriceX96) / 2 ** 96;
const token1PerToken0 = ratio * ratio;
const priceInWeth = isToken0 ? token1PerToken0 : 1 / token1PerToken0;
// ethUsd from any ETH oracle.
const priceUsd = priceInWeth * ethUsd;
const marketCapUsd = priceUsd * 1_000_000_000; // fixed supply
const fdvUsd = marketCapUsd; // supply is fixed; FDV equals market cap unless tokens are burned
const [pairedPrincipal, threshold, graduated] = await client.readContract({
address: factory,
abi: [parseAbiItem(
"function graduationStatus(address token) view returns (uint256 pairedPrincipal, uint256 threshold, bool graduated)"
)],
functionName: "graduationStatus",
args: [token],
});
const progress = Number(pairedPrincipal) / Number(threshold); // 0..1, the progress line
15. Fees and CTO state
The locker holds the per-token fee split and any pending CTO proposal. Reading it tells you the live, deployed values for a given token, which may differ from the launch config (see section 6).
import { parseAbi, zeroAddress } from "viem";
const lockerAbi = parseAbi([
"function tokenProtocolFeeShares(address token) view returns (uint256)",
"function feeRedirects(address token) view returns (address)",
"function protocolFeeRecipient() view returns (address)",
"function pendingCto(address token) view returns (address newWallet, uint64 executeAfter)",
]);
const [protocolShare, redirect, pending] = await Promise.all([
client.readContract({ address: locker, abi: lockerAbi, functionName: "tokenProtocolFeeShares", args: [token] }),
client.readContract({ address: locker, abi: lockerAbi, functionName: "feeRedirects", args: [token] }),
client.readContract({ address: locker, abi: lockerAbi, functionName: "pendingCto", args: [token] }),
]);
const creatorSharePercent = 100 - Number(protocolShare); // launch config: 90
const creatorPayout = redirect === zeroAddress ? deployer : redirect;
// pending.executeAfter is the unix time a proposed CTO can execute (0 = none). The 14-day veto
// window is CTO_TIMELOCK; the creator can cancel any time before it elapses.
16. RIFF Indexer API
For teams that do not want to run their own indexer, RIFF publishes a REST and WebSocket read layer. The base URL will be published at launch.
| Route | Description |
|---|---|
GET /tokens | List tokens, sortable (mcap, trending, lasttrade, new, oldest). |
GET /token/:address | Single token detail. |
GET /token/:address/candles | OHLC candles. |
GET /token/:address/trades | Recent trades. |
GET /token/:address/holders | Holder list. |
GET /token/:address/fees | Accrued fee state. |
GET /search | Token search. |
GET /wallet/:address/launches | Tokens launched by a wallet. |
GET /wallet/:address/holdings | Tokens held by a wallet. |
GET /wallet/:address/fees | Fees earned by a wallet. |
GET /stats | Platform-wide daily stats. |
| WebSocket | A live feed of updates, for teams that want push updates instead of polling. |
Selected response fields: imageUrl, launchBlock,
creatorFeeBps, protocolFeeBps, graduated,
burnedTokens, burnedPct on tokens; type,
ethAmount, tokenAmount, priceUsd, wallet,
isDev, ageSeconds, txHash on trades.
17. Reference and support
- A reference token address will be published at launch.
- Contracts are immutable: new versions ship as new addresses, never upgrades in place.
- Onchain data is public and free to read by anyone, with or without RIFF's indexer.
- Usage of RIFF and any token launched on it is at your own risk (see section 9).
- Support contact will be published at launch.