Clank V2 is deployed on Robinhood Chain. Start from the canonical factory and discover each launch token, bonding curve, and graduated pool through factory reads and events.
Canonical factory
0x798daAa0707C1e538bB5Acf0867Ac0e1A84cccF2
Current launch config
Robinhood Chain ID 4663, launch config ID 0.
Public Clank V2 addresses
These are the fixed entry points an integration may call directly. Protocol
operations contracts are intentionally omitted because apps do not need to
interact with them. The zero address,
0x0000000000000000000000000000000000000000, represents native ETH when used
as a pairToken.
| Contract | Address | Role |
|---|---|---|
| Launch factory | 0x798daAa0707C1e538bB5Acf0867Ac0e1A84cccF2 |
Creates launches, stores canonical records, and coordinates graduation. |
| Launch-and-buy forwarder | 0xac20d0d5cc0F89ee4f6d5f8E6870a36EAF2E0dD7 |
Atomically launches a token and executes its opening curve buy. |
The launch-and-buy address should still be read from launchForwarder() before
use. The owner can rotate that forwarder without replacing the factory.
Robinhood Uniswap contracts
| Contract | Address |
|---|---|
| Permit2 | 0x000000000022D473030F116dDEE9F6B43aC78BA3 |
| WETH | 0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73 |
| V4 PoolManager | 0x8366a39CC670B4001A1121B8F6A443A643e40951 |
| Universal Router | 0x8876789976decbfcbbbe364623c63652db8c0904 |
| V4 Quoter | 0x8dc178efb8111bb0973dd9d722ebeff267c98f94 |
Robinhood’s Universal Router uses the extended V4 exact-input tuple documented
in Trade after graduation. Do not substitute a
generic router ABI that omits minHopPriceX36.
Per-launch contracts
Every launch creates two deterministic contracts. Their addresses are not listed globally because they depend on the creator, metadata, economics, and salt.
| Contract | Discovery | Role |
|---|---|---|
ClankLauncherToken |
TokenLaunched.token or getLaunchedToken(launchToken) |
Burnable 18-decimal ERC-20 with immutable factory, curve, and deployer references. |
ClankBondingCurve |
TokenLaunched.curve or getLaunchedToken(launchToken).curve |
Quotes and executes pre-graduation buys and sells, then tracks migration state. |
| Uniswap V4 pool | Build its PoolKey from the launch record and initializationHook() |
Executes swaps after curve state PoolCreated. |
The V4 pool does not have a standalone contract address. Its identity is the hash of its currencies, fee, tick spacing, and hook inside the singleton PoolManager.
Canonical discovery
Do not accept a curve address supplied by an untrusted client. Resolve it from the factory and verify the bidirectional references when indexing or handling a high-value transaction.
import { parseAbi, type Address, type PublicClient } from "viem";
const CLANK_FACTORY = "0x798daAa0707C1e538bB5Acf0867Ac0e1A84cccF2";
const factoryDiscoveryAbi = parseAbi([
"function getLaunchedToken(address launchToken) view returns ((address launchToken,address curve,address deployer,address creatorFeeRecipient,address pairToken,uint256 graduationThreshold,uint24 poolFee,int24 tickSpacing,uint16 creatorTaxBps,bool buybackEnabled,uint8 phase,uint256 sweptPairToken,uint256 sweptLaunchTokens,uint256 sweptAt,bool exists) launched)",
"function initializationHook() view returns (address)",
]);
const tokenDiscoveryAbi = parseAbi([
"function launchFactory() view returns (address)",
"function curve() view returns (address)",
]);
const curveDiscoveryAbi = parseAbi([
"function factory() view returns (address)",
"function token() view returns (address)",
"function state() view returns (uint8)",
]);
export const resolveClankLaunch = async ({
publicClient,
launchToken,
}: {
publicClient: PublicClient;
launchToken: Address;
}) => {
const launch = await publicClient.readContract({
address: CLANK_FACTORY,
abi: factoryDiscoveryAbi,
functionName: "getLaunchedToken",
args: [launchToken],
});
if (!launch.exists) throw new Error("Not a Clank V2 launch token");
const [tokenFactory, tokenCurve, curveFactory, curveToken, state, hook] =
await Promise.all([
publicClient.readContract({
address: launchToken,
abi: tokenDiscoveryAbi,
functionName: "launchFactory",
}),
publicClient.readContract({
address: launchToken,
abi: tokenDiscoveryAbi,
functionName: "curve",
}),
publicClient.readContract({
address: launch.curve,
abi: curveDiscoveryAbi,
functionName: "factory",
}),
publicClient.readContract({
address: launch.curve,
abi: curveDiscoveryAbi,
functionName: "token",
}),
publicClient.readContract({
address: launch.curve,
abi: curveDiscoveryAbi,
functionName: "state",
}),
publicClient.readContract({
address: CLANK_FACTORY,
abi: factoryDiscoveryAbi,
functionName: "initializationHook",
}),
]);
const matches =
tokenFactory.toLowerCase() === CLANK_FACTORY.toLowerCase() &&
curveFactory.toLowerCase() === CLANK_FACTORY.toLowerCase() &&
tokenCurve.toLowerCase() === launch.curve.toLowerCase() &&
curveToken.toLowerCase() === launchToken.toLowerCase();
if (!matches) throw new Error("Clank launch references do not match");
return { ...launch, state, hook } as const;
};Factory interface
Reads
| Function | Returns or purpose |
|---|---|
launchEnabled() |
Global gate for new launches. Existing trading and graduation continue when disabled. |
canLaunch(address) |
Whether an account may launch through the public gate. |
launchConfigCount() |
Number of zero-indexed launch configurations. |
getLaunchConfig(id) |
Supply, curve fee, native economics, V4 fee, tick spacing, and enabled flag. |
approvedPairTokens(pairToken) |
Whether an ERC-20 may be used for new launches. |
pairTokenEconomics(pairToken) |
ERC-20 virtual reserve, graduation threshold, and expected decimals. |
previewLaunchEconomics(id, pairToken) |
Commitment hash used to pin launch economics. |
predictLaunch(creator, params, id, pairToken) |
Predicted token, curve, and launch ID. |
getLaunchedToken(launchToken) |
Compact Pons V2-compatible launch record. |
getLaunch(launchToken) |
Full Clank launch record, including snapshotted economics and graduation result. |
launchForwarder() |
Current trusted atomic launch-and-buy contract. |
initializationHook() / memeHook() |
Clank and Pons-compatible getters for the V4 hook. |
launchFee() |
Native launch fee; currently zero. |
Public writes
| Function | Purpose |
|---|---|
launchToken(params, id, pairToken) |
Create a token and curve. |
launchToken(params, id, pairToken, exemptions) |
Create a launch with additional snipe-tax exemptions. |
graduate(launchToken) |
Permissionlessly move a Ready curve to Swept. |
createGraduatedPool(launchToken) |
Permissionlessly create and lock the pool for a Swept launch. |
Configuration and protocol operations are managed by Clank. A regular integration should only request signatures for the public launch, trading, and graduation methods documented here.
Bonding-curve interface
| Function | Purpose |
|---|---|
state() |
Exact lifecycle state used for routing. |
token() / pairToken() / factory() |
Immutable launch references. |
feeBps() |
Snapshotted curve fee in basis points. |
currentSnipeTaxBps(recipient) |
Current recipient-specific total buy tax. |
getReserves() |
Effective pair-token and launch-token reserves used for pricing. |
realPairTokenReserve() |
Not exposed under this name; use realQuoteReserve() in the Pons-compatible ABI. |
realQuoteReserve() / realTokenReserve() |
Tracked real reserves, excluding virtual reserves and donations. |
quoteBuyFor(recipient, pairTokenIn) |
Buy quote including recipient-specific tax and a possible terminal refund. |
quoteSell(launchTokensIn) |
Gross pair-token output, net output, and fee. |
buy(pairTokenIn, minLaunchTokensOut, recipient) |
Execute a curve buy. Native launches require matching msg.value. |
sell(launchTokensIn, minPairTokenOut, recipient) |
Execute a curve sell after approving the curve for launch tokens. |
The ABI retains quote names such as realQuoteReserve for Pons V2
compatibility. The guides use pairToken terminology for the asset itself.
Curve state
| State | Value | Meaning |
|---|---|---|
Trading |
0 |
Curve buys and sells are enabled. |
Ready |
1 |
Sale allocation is exhausted; reserves await sweeping. |
Swept |
2 |
Factory holds reserves for pool creation. |
PoolCreated |
3 |
Trading routes through Uniswap V4. |
Rescued |
4 |
Delayed recovery completed; no automatic venue remains. |
Launch-token interface
Every launch token implements the standard ERC-20 and ERC-20 burnable methods. It uses 18 decimals and has no owner, mint function, transfer tax, pause, proxy, or upgrade path.
| Function | Purpose |
|---|---|
deployer() |
Original launch creator. |
launchFactory() |
Factory that created the launch. |
curve() |
Token’s dedicated bonding curve. |
logo() / description() / socials() |
Onchain launch metadata. |
getTokenInfo() |
Pons-compatible creator and metadata tuple. |
burn(amount) / burnFrom(account, amount) |
Standard ERC-20 burnable functions. |
The initial fixed supply is minted entirely to the curve. Burning is voluntary and reduces total supply; there is no method to mint replacement tokens.
Launch-and-buy interface
launchAndBuy(params, configId, pairToken, pairTokenIn, minLaunchTokensOut, recipient, exemptions) creates the launch and executes its
first curve buy atomically.
- Native launches send
launchFee + pairTokenInasmsg.value. - ERC-20 launches approve the current forwarder for
pairTokenInand send onlylaunchFeeas native value. - The forwarder refunds any terminal overpayment to the launcher.
- It appends the opening-buy recipient to the snipe-tax exemption list.
Resolve the address with launchForwarder() and verify its factory() before
approval. See Launch a token for a complete flow.
Integration ABI
Use focused ABIs for the methods your integration calls. These fragments cover the main launch, trade, graduation, and indexing surfaces.
import { parseAbi } from "viem";
export const clankFactoryAbi = parseAbi([
"function launchEnabled() view returns (bool)",
"function canLaunch(address launcher) view returns (bool)",
"function launchConfigCount() view returns (uint256)",
"function getLaunchConfig(uint256 id) view returns ((uint256 supply,uint256 curveFeeBps,uint256 phantomQuote,uint256 graduationThreshold,uint24 poolFee,int24 tickSpacing,bool enabled))",
"function approvedPairTokens(address pairToken) view returns (bool)",
"function pairTokenEconomics(address pairToken) view returns (uint256 phantomQuote,uint256 graduationThreshold,uint8 decimals)",
"function previewLaunchEconomics(uint256 launchConfigId,address pairToken) view returns (bytes32)",
"function predictLaunch(address creator,(string name,string symbol,string logo,string description,(string twitter,string telegram,string discord,string website,string farcaster) socials,address creatorFeeRecipient,uint16 creatorTaxBps,bool buybackEnabled,bytes32 expectedEconomics,bytes32 salt) params,uint256 launchConfigId,address pairToken) view returns (address launchToken,address curve,bytes32 launchId)",
"function launchToken((string name,string symbol,string logo,string description,(string twitter,string telegram,string discord,string website,string farcaster) socials,address creatorFeeRecipient,uint16 creatorTaxBps,bool buybackEnabled,bytes32 expectedEconomics,bytes32 salt) params,uint256 launchConfigId,address pairToken) payable returns (address launchToken,address curve)",
"function getLaunchedToken(address launchToken) view returns ((address launchToken,address curve,address deployer,address creatorFeeRecipient,address pairToken,uint256 graduationThreshold,uint24 poolFee,int24 tickSpacing,uint16 creatorTaxBps,bool buybackEnabled,uint8 phase,uint256 sweptPairToken,uint256 sweptLaunchTokens,uint256 sweptAt,bool exists) launched)",
"function launchForwarder() view returns (address)",
"function initializationHook() view returns (address)",
"function graduate(address launchToken)",
"function createGraduatedPool(address launchToken) returns (uint256 positionId)",
]);
export const clankCurveAbi = parseAbi([
"function factory() view returns (address)",
"function token() view returns (address)",
"function pairToken() view returns (address)",
"function state() view returns (uint8)",
"function feeBps() view returns (uint256)",
"function getReserves() view returns (uint256 pairTokenReserve,uint256 launchTokenReserve)",
"function realQuoteReserve() view returns (uint256)",
"function realTokenReserve() view returns (uint256)",
"function quoteBuyFor(address recipient,uint256 grossPairTokenIn) view returns (uint256 grossPairTokenUsed,uint256 netPairTokenIn,uint256 fee,uint256 launchTokensOut,uint256 pairTokenRefund)",
"function quoteSell(uint256 launchTokensIn) view returns (uint256 grossPairTokenOut,uint256 netPairTokenOut,uint256 fee)",
"function buy(uint256 pairTokenIn,uint256 minLaunchTokensOut,address recipient) payable returns (uint256 launchTokensOut)",
"function sell(uint256 launchTokensIn,uint256 minPairTokenOut,address recipient) returns (uint256 pairTokenOut)",
]);
export const clankTokenAbi = parseAbi([
"function name() view returns (string)",
"function symbol() view returns (string)",
"function decimals() view returns (uint8)",
"function totalSupply() view returns (uint256)",
"function balanceOf(address account) view returns (uint256)",
"function allowance(address owner,address spender) view returns (uint256)",
"function approve(address spender,uint256 amount) returns (bool)",
"function transfer(address recipient,uint256 amount) returns (bool)",
"function burn(uint256 amount)",
"function deployer() view returns (address)",
"function launchFactory() view returns (address)",
"function curve() view returns (address)",
"function logo() view returns (string)",
"function description() view returns (string)",
"function socials() view returns (string twitter,string telegram,string discord,string website,string farcaster)",
]);Events
Factory
| Event | Use |
|---|---|
TokenLaunched |
Discover the token, curve, creator, pair token, config ID, and threshold. |
LaunchSwept |
Record reserves moved from a Ready curve into the factory. |
PoolGraduated |
Mark the V4 pool as created and store its position and seeded amounts. |
LaunchForceSwept |
Record exceptional delayed reserve sweeping. |
LaunchGraduationRescued |
Record exceptional delayed recovery. |
LaunchConfigAdded / LaunchConfigUpdated |
Refresh factory configuration for future launches. |
LaunchConfigEnabledUpdated / LaunchEnabledUpdated |
Refresh launch availability. |
PairTokenApprovalUpdated / PairTokenEconomicsUpdated |
Refresh pair-token support and economics. |
LaunchForwarderSet |
Refresh the atomic launch-and-buy target. |
Curve
| Event | Use |
|---|---|
CurveBuy |
Record buyer, recipient, pair-token input, launch-token output, fee, and tax. |
CurveBuyRefunded |
Record pair tokens returned by a terminal buy. |
CurveSell |
Record seller, recipient, launch-token input, pair-token output, fee, and tax. |
StateChanged |
Track the exact lifecycle transition. |
CurveCompleted |
Record reserve transfer out of the curve. |
AutoGraduationFailed |
Queue a permissionless graduation retry. |
Launch-and-buy forwarder
| Event | Use |
|---|---|
Launched |
Record the atomic launch recipient, launcher, requested spend, and received tokens. |
Use (chainId, transactionHash, logIndex) as an event’s durable identity and
handle chain reorgs. See Index the protocol for the
recommended indexing flow.