Abyssal
Connect wallet

Integrations

A coin here is an ordinary ERC-20 in an ordinary Uniswap V3 pool on Ink (chain id 57073). If your tooling speaks Uniswap V3, it already speaks Abyssal.


Trading

Route through the canonical SwapRouter02 at 0x177778F19E89dD1012BdBe603F144088A95C4B53 with exactInputSingle, fee tier 10000 (1%).

  • Before the bond: COIN / USDT0
  • After: COIN / TRACKER

USDT0 is 0x0200C29006150606B650577BBE7B6248F58470c1 (6 decimals). To trade from ETH, go through the WETH/USDT0 pool at the 0.30% tier (0x356667DA30C89cC36c65D394500424d5Eba8731c, fee 3000) — that is where Ink's WETH/USDT0 liquidity sits; the 0.05% pool is nearly empty.

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 0x96b572D2d880cf2Fa2563651BD23ADE6f5516652. 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, quote the whole path at once or 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.usdt0() means pre-bond, anything else means the coin is paired to its tracker.

The launcher's address is published in Architecture once the Ink deployment is live, with its source verified on Ink Explorer.

Launching programmatically

launch(LaunchParams) pulls the seed USDT0 from the caller (approve the launcher first). launchWithEth(LaunchParams) is payable: it buys the seed with the ETH sent along through the WETH/USDT0 0.30% pool, refunds the remainder, and needs no approval. Both require seedUsdt0In ≥ minSeedUsdt0() (1 USDT0) and leverage between 1 and LTFactory.maxLeverageFor(underlyingSymbol). The creator is msg.sender in both cases.

Events

EventMeaning
Launched(coin, lt, pool, oracle, creator, positionTokenId, coinPriceUsdX18, graduationTargetUsdX18)a coin and its pool exist
SeedBought(coin, creator, usdt0In, ltSpent, coinOut)the creator's launch-block seed buy
Bonded(coin, lt, pool, positionTokenId, backingUsdt0)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.

Coins show up on DexScreener and GeckoTerminal under the ink network slug (https://dexscreener.com/ink/<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, abyssal on Goldsky (network ink), covering the launcher, the pools and the trackers; its endpoint is published with the deployment.

Reading a tracker's position

A tracker's vault is its own account on Nado, Ink's perpetuals exchange, so the hedge behind it is addressable by the vault's address:

LTFactory.venueRouting(lt)               → (productId, trader)   // trader == lt
LTVault.hedgeSubaccount()                → bytes32: vault address ++ "default"
LTVault.hedgeQuoteBalanceX18()           → the account's USDT0, x18, from Nado's spot engine
LTVault.hedgePerpBalanceX18(productId)   → (amount, vQuoteBalance), x18, from Nado's perp engine
LTVault.hedgeSigner()                    → the key the vault owner authorised to trade it

Nado's gateway serves the same account with no key: https://gateway.prod.nado.xyz/v1/query?type=subaccount_info&subaccount=<hedgeSubaccount> (balances, positions and health) and query?type=linked_signer&subaccount=<hedgeSubaccount>; query?type=symbols lists every market with its product id, margin weights, minimum size and trading status. Every request must send Accept-Encoding: gzip. The Nado contracts a vault calls are the Endpoint at 0x05ec92D78ED421f3D3Ada77FFdE167106565974E and the Clearinghouse at 0xD218103918C19D0A10cf35300E4CfAfbD444c5fE. 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. The only restricted calls are claimCreatorFees (the creator of that coin), the locker's lock/migrateToLt (the launcher), and a vault's hedge controls — setHedgeSigner, revokeHedgeSigner and requestHedgeWithdrawal for its owner, depositToHedge and linkHedgeSigner for its owner or the key the owner chose.