---
title: "Contracts"
description: "Public Clank V2 contracts, interfaces, and events for integrations."
---

> Documentation Index
> Fetch the complete documentation index at: https://developer.clank.trade/llms.txt
> Use this file to discover all available pages before exploring further.

# Contracts

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`.

> **Use the V2 factory**
>
> Resolve launches through the factory above. Older Clank deployments may still
> contain active tokens, but new V2 launches and current configuration reads use
> this address.

## 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](/guides/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.

```ts title="resolve-clank-launch.ts"
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. |

> **Curve state and compatibility phase differ**
>
> `getLaunchedToken().phase` uses the compact Pons-compatible mapping: `0`
> covers both `Trading` and `Ready`, `1` is `Swept`, `2` is `PoolCreated`, and
> `3` is `Rescued`. Read `state()` from the curve for routing decisions.

## 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](/guides/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.

```ts title="clank-abi.ts"
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](/guides/index-the-protocol) for the
recommended indexing flow.

Source: https://developer.clank.trade/reference/contracts/index.mdx
