PAIR
Launch coin

Contracts

Deployed on Arbitrum One, chain ID 42161, on 2026-09-10 at block 503738330. Verification on Arbiscan follows as soon as an explorer key is on hand (contracts/verify.sh); until then the source in contracts/src is the contract, and the bytecode on chain is what forge build produces from it.

contractwhat it doesaddress
PairLaunchpadthe one-transaction launch: deploy, open the pool, seed it, record it0xaf1Fba97FF4F572c85Cc839a10C8f07317c127F8
FeeVaultowns every position forever; collects and splits fees creator / buyback0xF77613E904c15bEc41fE60c3Af01087Ed4115903
QuoteRegistryeligibility decisions, with manual overrides on top of the gates0x9d47734706Ab5FfC1E4Fe4290d8A5B65418419e6
CompositeQuoteGateasks every venue and takes the best answer0x67BB97C4c77d0Fa574359343532A3B4917DaE0e7
UniV3QuoteGate (Uniswap V3)depth from Uniswap V3's own oracle, every fee tier0x6E90A31B89bFF6598cAe88e1F77Bd40F5AF0Ebe8
CamelotQuoteGatedepth from Camelot's Algebra pools, through getTimepoints0xE65557CFA7015DA2971B6200414A26DF5E68231D
UniV3QuoteGate (PancakeSwap V3)the same contract pointed at Pancake's factory and tiers0xa0e92e7FfccC7810fC4523b8d5a26643835Eb50a
UniV3QuoteGate (SushiSwap V3)the same contract pointed at Sushi's factory0xB1500eE9A014B2CFB702B3E004e73D3F5e82087F
SampledV4QuoteGateUniswap v4 pools, walked tick by tick0x29FD1598cF9207F65A167aE5e7c433FEbFd02361
V2QuoteGateUniswap V2, SushiSwap V2 and Camelot's classic pairs, from reserves0x058cDd3D245dfE4f19cE864122AD9134d4BEa52a
PairBuybackwhere the protocol's share goes once $PAIR exists — written, tested, not deployed

Your coin's own contract

Every coin launched here is a PairToken, and every one of them shows as verified without anyone submitting it. That is not a courtesy — PairToken takes no constructor arguments (it calls back into the launchpad for its name, symbol and supply), so the creation bytecode is byte-identical every time. One instance gets verified; the explorer matches all the others, including coins that do not exist yet.

What that verified source says, and what it therefore cannot do: fixed supply set once in the constructor, no mint function, no transfer tax, no blacklist, no pause, no owner.

External contracts it uses

Every address below was read back on Arbitrum One before being written down.

Uniswap v4 PoolManager0x360E68faCcca8cA495c1B759Fd9EEe466db9FB32
Uniswap v4 StateView (the interface reads through it)0x76Fd297e2D437cd7f76d50F01AfE6160f86e9990
Uniswap v4 Quoter (the interface prices through it)0x3972C00f7ed4885e145823eb7C655375d275A1C5
Uniswap V3 factory (measurement only)0x1F98431c8aD98523631AE4a59f267346ea31F984
Camelot AMM v3 (Algebra) factory (measurement only)0x1a3c9B1d2F0529D97f2afC5136Cc23e58f1FD35B
PancakeSwap V3 factory (measurement only)0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865
SushiSwap V3 factory (measurement only)0x1af415a1EbA07a4986a52B6f2e7dE7003D82231e
Uniswap V2 factory (measurement only)0xf1D7CC64Fb4452F05c498126312eBE29f30Fbcf9
SushiSwap V2 factory (measurement only)0xc35DADB65012eC5796536bD9864eD8773aBc74C4
Camelot classic-pair factory (measurement only)0x6EcCab422D763aC031210895C81787E87B43A652
Chainlink ETH/USD0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612
Chainlink BTC/USD0x6ce185860a4963106506C203335A2910413708e9

The anchors — the assets every depth reading is priced through — are WETH, native USDC, USD₮0, WBTC and the bridged USDC.e. Five rather than three, because Arbitrum's dollar liquidity is split between three dollar tokens and reading only one would call a real market thin.

Calls worth knowing

Before launching

// Non-reverting. Returns whether it would be allowed, and why not if not.
registry.status(address quote)
  returns (bool eligible, Decision decision, Report report)

// The bar this particular asset has to clear — $15,000 if listed, $50,000 if not.
registry.requiredDepthUsdE8(address quote) returns (uint256)

Naming a v4 pool

Every other venue can be searched: a factory answers getPair(a, b), getPool(a, b, fee) or poolByPair(a, b). Uniswap v4's singleton cannot — a pool is identified by the hash of its key, and the key contains a 160-bit hook address, so it can be verified but never enumerated. A v4 pool therefore has to be named once before the gate can see it. Anyone may do it, once, for everyone.

v4Gate.registerPool(PoolKey key) returns (address token)
v4Gate.registerLaunch(address token) returns (address)   // for a coin launched here
v4Gate.probe(PoolKey key) returns (uint256 usdE8, address anchor)   // read-only, changes nothing

Nothing equivalent is needed for the V2-shaped venues, for the V3-shaped ones or for Camelot: those are searched directly, so a coin with a market there is usable the moment its address is pasted in.

Launching

launchpad.launch(LaunchConfig cfg) payable returns (address token, bytes32 poolId)
launchpad.predictToken(address creator, bytes32 salt) returns (address)
launchpad.launchFee() returns (uint256)

LaunchConfig carries, beyond the obvious:

fieldwhat it does
creatorBpsshare of supply kept back for you, capped at 20%
feeRoute0 keeps your fees, 1 buys the coin back and burns it
feeRecipientzero means the launching wallet
devBuyQuotepair-asset amount spent buying your own coin as the pool's first trade; needs an approval to the launchpad first
devBuyMinOutleast you will accept from that buy — nobody can front-run it, so this guards against you and the pool disagreeing on the opening price

After launching

// Anyone can call. Proceeds only ever reach the recorded recipient, the sink and the treasury.
feeVault.collect(address token)

// Creator only. Both take effect from the next collect.
feeVault.setFeeRoute(address token, FeeRoute route)
feeVault.setFeeRecipient(address token, address recipient)

// Reads
launchpad.launchOf(address token)                              // a public mapping: an unnamed tuple
feeVault.launchOf(address token) returns (Launch)              // includes the PoolKey
feeVault.feeRouteOf(address token) returns (FeeRoute)
feeVault.feeRecipientOf(address token) returns (address)
feeVault.owed(address token, address who) returns (uint256)    // a payout that could not be pushed
feeVault.claim(address token)                                  // collect one

Where the liquidity lock actually lives

There is no lock contract and no locked LP token, because Uniswap v4 has no LP tokens at all — a position is a storage slot keyed by (owner, tickLower, tickUpper, salt). The usual "liquidity locked" detectors look for LP tokens sent to a burn address or a locker, and here there is nothing of the sort for them to find.

What holds instead is a property of FeeVault, and its source is published so you can check it rather than believe it: no code path in the vault ever passes a negative liquidityDelta. Collecting fees calls modifyLiquidity with a delta of exactly zero. There is no withdraw, no emergency exit, and no owner function that adds one. The float cannot come back out — not by the creator, not by us.

Owner powers

The owner can retune the depth bars, the fee bounds, the launch fee, the treasury, the buyback sink, the curated list, the gates and their parameters. It cannot touch a launch's liquidity, change an existing launch's creator share, or redirect a creator's fees.

Ownership transfer is two-step everywhere: a handover that is never accepted leaves the current owner in place rather than sending the protocol to a wrong address.

The deploy script hands ownership to whatever OWNER names. It should be a multisig behind a timelock, and the contracts do not enforce that themselves.

None of this has been audited.