Integrations
A coin here is an ordinary ERC-20 in an ordinary Uniswap V3 pool on Avalanche C-Chain (chain id 43114). If your tooling speaks Uniswap V3, it already speaks Flake Fun.
Not deployed yet. Flake Fun's own contracts are not on Avalanche yet; their addresses will be listed in Architecture at launch, with verified sources on Snowtrace. The Uniswap, USDC and CCTP addresses on this page are live on Avalanche today (code read on chain 2026-09-21).
The chain, for integrators
- Chain id
43114(0xa86a). Public RPCs includehttps://api.avax.network/ext/bc/C/rpc(rate-limited; WebSocketwss://api.avax.network/ext/bc/C/ws),https://avalanche-c-chain-rpc.publicnode.comandhttps://avalanche.drpc.org; for anything serious, use a keyed endpoint. - Log ranges depend on the provider. On 2026-09-21 the public RPC refused
eth_getLogsover more than 2,048 blocks per call. Scan in windows of 2,000 there, and size the window to your provider otherwise. - Blocks about every second (1.05 s on average over 1,000 blocks, read on chain 2026-09-21), final within a second or two. The block time is dynamic and can drop below a second, so several blocks can share one timestamp. Key anything time-based on block numbers.
- Gas is AVAX. Fees are EIP-1559-style with a dynamic base fee and no fixed floor: on 2026-09-21 the base fee was 0.057 gwei, so 150,000 gas cost about 0.00002 AVAX. Price from
eth_feeHistory/eth_maxPriorityFeePerGasrather than a constant. - Multicall3 is at the usual
0xcA11bde05977b3631167028862bE2a173976CA11. viem's built-inavalanchechain is complete (RPC, explorer, Multicall3); only the RPC needs overriding with a keyed one. - USDC is an ordinary ERC-20 (Circle's FiatToken, 6 decimals) at
0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E. Do not confuse it with USDC.e at0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664, the older bridged token: no pool or contract here uses it.
Trading
Route through the canonical SwapRouter02 at 0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE with exactInputSingle, fee tier 10000 (1%).
- Before the bond:
COIN / USDC - After:
COIN / TRACKER
USDC is 0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E (6 decimals). Pay with the token and an approval. No coin is paired with AVAX or WAVAX, and our own contracts take no native value, so there is no other asset to route through: every coin is one hop from USDC before its bond, two after.
After the bond, a USDC buy is USDC → TRACKER → COIN: first the tracker's own USDC pool at the 0.05% tier (fee 500), then the coin's pool at 1%. Use exactInput with the whole path. The first leg can also be done off-pool: LTVault.mint(usdcIn, minSharesOut) mints the tracker at its NAV, with no slippage on that leg — which is how the launcher's own seed buy does it. It reverts while the vault is paused or its NAV is stale.
The coin is always token0 — it is CREATE2-mined to sort below both USDC and its tracker — so the side of a swap is known without reading the pool, and price is quoted the right way up by default.
That guarantee is for a coin's pool only. A tracker's own USDC reference pool has no mined address: against Avalanche's USDC (0xB97E…8a6E) roughly seven tracker addresses in ten sort below it, so USDC is token1 in most tracker/USDC pools and token0 in the rest. Read token0() before pricing or routing through one.
Quote with QuoterV2 at 0xbe0F5544EC67e9B3b2D979aaA43f18Fd87E6257F. Its quote functions are not declared view: they simulate the swap and unwind it, so call them with eth_call (or your library's simulate), not as a view and not in a transaction.
One warning from our own mistakes: chaining a multi-leg quote by calling the quoter once per leg gives nonsense, because each leg quotes against the current state rather than the state the previous leg would have left. Quote the whole path at once (quoteExactInput) or simulate on a fork.
The other canonical Uniswap addresses on Avalanche — factory, position manager, V4 — are listed in Architecture.
Discovering coins
The launcher is the registry. No indexer required:
MemeLauncherV3.allCoinsLength() → uint256
MemeLauncherV3.allCoins(uint256) → address
MemeLauncherV3.coinOf(address) → (quote, lt, oracle, creator, pool,
positionTokenId, tickLower, tickUpper,
graduationTargetUsdX18, graduated)
MemeLauncherV3.lockedLtPrincipal(coin) → the quote side of the locked position: the coin's backingquote tells you the stage: equal to MemeLauncherV3.usdc() means pre-bond, anything else means the coin is paired to its tracker. lt is filled in from the launch block either way — the launcher resolves the tracker at launch, because the coin's address has to sort below it. lockedLtPrincipal is in the quote's units: 6-decimal USDC before the bond, 18-decimal tracker after.
The thresholds are public too: bondBackingUsd() (15,000 USDC), minSeedUsdc() (1 USDC) and minRefPoolUsdc() (500 USDC).
Launching programmatically
launch(LaunchParams) is the one entry point. It pulls the seed buy (seedUsdcIn) plus any reference-pool seed (refPoolSeedUsdc) from the caller in USDC, so approve the launcher for that total first; it checks both balance and allowance before deploying anything, and fails with InsufficientSeedUsdc or SeedAllowanceMissing rather than a bare transfer error. The launcher takes no native value.
seedUsdcInmust be at leastminSeedUsdc()(1 USDC), or it revertsSeedTooSmall.leveragemust be between 1 andLTFactory.maxLeverageFor(underlyingSymbol), which is 0 for a market the factory has not listed.quoteInUsdc = trueis what the app sends: the coin trades against USDC and bonds later.falsequotes the coin in its tracker from the first block, and is refused (ReferencePoolTooThin) unless the tracker's USDC pool already holds at leastminRefPoolUsdc().navPostcarries a keeper-signed first NAV, used only when the launch creates the tracker; an empty signature skips it.- The creator is
msg.sender: the seed payer, the recipient of the seed coins and the owner of the fee stream.
Events
| Contract | Event | Meaning |
|---|---|---|
| launcher | Launched(coin, lt, pool, oracle, creator, positionTokenId, coinPriceUsdX18, graduationTargetUsdX18) | a coin and its pool exist |
| launcher | SeedBought(coin, creator, usdcIn, ltSpent, coinOut) | the creator's launch-block seed buy |
| launcher | Bonded(coin, lt, pool, positionTokenId, backingUsdc) | the coin re-paired to its tracker; the market moved to a new address |
| locker | FeesCollected(coin, caller, amount0, amount1) | swap fees swept out of the position |
| locker | CreatorFeesClaimed(coin, creator, amount0, amount1) | a creator withdrew their share |
| factory | SharedLtCreated(lt, oracle, underlyingSymbol, isShort, leverage) | a new tracker exists |
| factory | LtRoutingSet(lt, marketId, trader) | a tracker's Lighter market and hedge wallet |
| factory | Bonded(lt, depthUsd) | a tracker bonded: NAV now follows its oracle, the hedge is enabled |
| tracker vault | HedgeFunded(to, amount) | USDC sent to the hedge wallet, bound for Lighter |
| tracker vault | HedgeFunderUpdated(funder) | the hedge wallet changed; 0x0 is the kill switch |
| NAV oracle | NavPosted(nav, hedgeEquityUsd, underlyingPrice, timestamp) | a fresh signed NAV |
Bonded on the launcher is the one to handle carefully: the pool address changes, so a tape built on the old pool ends there and a new one begins. The coin is the stable identifier across both.
Indexing the tape
The pool is the tape. Watch its own Swap events and a trade placed by a bot you have never heard of, through a router you do not know, is indexed exactly like one placed on our own front. There is no proprietary event to decode and no zap to special-case.
Coins show up on DexScreener and GeckoTerminal under the Avalanche network slugs — avalanche on DexScreener, avax on GeckoTerminal (https://dexscreener.com/avalanche/<pool>, https://www.geckoterminal.com/avax/pools/<pool>), keyed by the pool address — so after a bond, look the coin up again by its new pool.
Our own indexer is a subgraph, flake-fun on Goldsky (network avalanche), covering the launcher, the pools, the trackers and every HedgeFunded payment. Its endpoint is published with the deployment. Wallet login on the site is through Privy, with Avalanche as the chain.
Reading a tracker's position
A tracker's position is not on Avalanche. It sits in a Lighter account held by the protocol's hedge wallet, because a contract cannot own a Lighter account. What Avalanche does record is the routing and every dollar that leaves a vault or comes back to it:
LTFactory.venueRouting(lt) → (marketId, trader) // Lighter market id; trader = the hedge wallet
LTFactory.underlying(symbol) → (marketId, maxLeverage, listed)
LTVault.hedgeFunder() → the only address fundHedge can pay; 0x0 = cut off
LTVault.fundableUsdc() → what the vault could send it right now
LTVault.bonded() → false: NAV pinned at 1.0, nothing can leave for the venue
LTVault.targetLeverageX(), isShort(), leverageBandBps()
NAVOracle.peekNav() → (nav, updatedAt, stale), never reverts
NAVOracle.hedgeEquityUsd() → the tracker's share of the account equity the keeper signed with the last NAVLighter takes deposits straight from Avalanche and pays fast withdrawals on Arbitrum, so the way back runs through Circle's CCTP V2 (TokenMessengerV2 0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d and MessageTransmitterV2 0x81D40F21F12A8F0E3252Bccb954D722d4c464B64 on Avalanche, the same addresses on Arbitrum per Circle's docs; Avalanche is domain 1, Arbitrum domain 3). The trail, leg by leg:
HedgeFunded(to, amount)on the vault, on Avalanche;- the wallet's USDC
Transferto Lighter's deposit address for it, on Avalanche (a plain transfer to an address with no code); - coming back: Lighter's fast-withdrawal payout to the wallet on Arbitrum (a USDC
Transferinto the wallet there), the wallet'sdepositForBurnon Arbitrum (destination domain1, mint recipient the vault), and on Avalanche a USDCTransferfrom the zero address to the vault in the same transaction asMessageTransmitterV2'sMessageReceived. Match a return on the CCTP message (nonce or source transaction), not on the amount alone.
Lighter's public API serves every market with no key, at https://mainnet.zklighter.elliot.ai:
/api/v1/orderBooks— every market with its integermarket_id, symbol, size and price decimals and minimum sizes;/api/v1/orderBookDetails?market_id=110— Nvidia's mark, index and last price, margin fractions, status and open interest; with nomarket_id, every market in one answer;/api/v1/funding-rates— every market's current funding rate on Lighter and on reference venues;/api/v1/fundings?market_id=110&resolution=1h— the settled hourly funding history.
A public WebSocket (wss://mainnet.zklighter.elliot.ai/stream) streams order books, trades and market stats. Lighter publishes rate limits only for keyed tiers; excess requests get HTTP 429. Account balances and positions are not public: they need that account's credentials. See The hedge book.
Permissions
Everything a trader, a creator or an integrator needs is permissionless: swap, quote, launch, read, bond a coin (bondAndMigrate) or a tracker (pokeBond), collect fees, claim protocol fees, mint and redeem trackers at NAV, execute the redemption queue, rebalance a tracker's reference pool, and relay a NAV the keeper has already signed. The restricted calls are:
claimCreatorFees— the creator of that coin;- the locker's
lock/migrateToLt— the launcher; - the factory's
getOrCreateSharedLt— an authorised launcher; its listing, routing and defaults — the factory owner; - a vault's
fundHedge— its owner or its hedge wallet, paying only the hedge wallet; - a vault's
setHedgeFunder,setPaused,setFeesand other settings — its owner; cancelRedeem— the holder who queued the redeem.