Skip to content

Contracts

Public Clank V2 contracts, interfaces, and events for integrations.

Updated View as Markdown

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.

resolve-clank-launch.tsts
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 + pairTokenIn as msg.value.
  • ERC-20 launches approve the current forwarder for pairTokenIn and send only launchFee as 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.

clank-abi.tsts
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.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close