Integrations
A coin here is an ordinary ERC-20 in an ordinary Uniswap V3 pool on Base. If your tooling speaks Uniswap V3, it already speaks Leverage.
Trading
Route through the canonical SwapRouter02 at 0x2626664c2603336E57B271c5C0b26F421741e481 with exactInputSingle, fee tier 10000 (1%).
- Before the bond:
COIN / USDC - After:
COIN / TRACKER
The coin is always token0 — it is CREATE2-mined to sort below its quote — so the side of a swap is known without reading the pool, and price is quoted the right way up by default.
Quote with QuoterV2 at 0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a. Note that it is not a view function: it reverts with the answer encoded in the revert data, and a naive eth_call treated as a failure will silently drop your quote.
One warning from our own mistakes: chaining a multi-leg quote by calling the quoter twice gives nonsense, because each leg quotes against the current state rather than the state the previous leg would have left. If you need a chained figure, simulate on a fork.
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)quote tells you the stage: equal to MemeLauncherV3.usdc() means pre-bond, anything else means the coin is paired to its tracker.
The launcher is at 0x3D52129945443911052910409F78D55cb7623A30 (see Architecture); its source is verified on Basescan.
Launching programmatically
launch(LaunchParams) pulls the seed USDC from the caller (approve the launcher first). launchWithEth(LaunchParams) is payable: it buys the seed with the ETH sent along through the WETH/USDC 0.05% pool, refunds the remainder, and needs no approval. Both require seedUsdcIn ≥ minSeedUsdc() (1 USDC) and leverage between 1 and LTFactory.maxLeverageFor(underlyingSymbol). The creator is msg.sender in both cases.
Events
| Event | Meaning |
|---|---|
Launched(coin, lt, pool, oracle, creator, positionTokenId, coinPriceUsdX18, graduationTargetUsdX18) | a coin and its pool exist |
SeedBought(coin, creator, usdcIn, ltSpent, coinOut) | the creator's launch-block seed buy |
Bonded(coin, lt, pool, positionTokenId, backingUsdc) | the coin re-paired to its tracker; the market moved to a new address |
FeesCollected(coin, caller, amount0, amount1) | swap fees swept out of the position |
CreatorFeesClaimed(coin, creator, amount0, amount1) | a creator withdrew their share |
Bonded 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.
Reading a tracker's position
A tracker's vault is its own trader on Avantis, so the hedge behind it is addressable by the vault's address:
LTFactory.venueRouting(lt) → (pairIndex, trader) // trader == lt
LTVault.hedgeTradesCount(pairIndex) → open positions
LTVault.hedgeTrade(pairIndex, i) → one position, straight from TradingStorageThe same positions are served by the venue at https://prod-api.avantisfi.com/core/user-data?trader=<vault address>, and the pair catalogue (index, symbol, max leverage, fees, price feed id) at https://prod-api.avantisfi.com/data/v2/trading. See The hedge book.
Permissions
Everything a trader, a creator or an integrator needs is permissionless: swap, quote, launch, read, bond, collect fees, claim protocol fees, sync a vault's hedge allowance. The only restricted calls are claimCreatorFees (the creator of that coin), the locker's lock/migrateToLt (the launcher), and the vault owner's delegate and allowance controls.