AscntDocs
For Builders

Targeting Ascnt Pools

Identify, verify, and interact with an Ascnt pool, and read its data from the subgraph.

An Ascnt Pool is identified the same way as any Uniswap v4 pool — by its PoolKey and the PoolId derived from it — and you interact with it through the standard v4 contracts. The whole flow: identify the pool, verify it's genuine, interact, and read its data.

Identify the pool

PoolKey

struct PoolKey {
    Currency currency0;   // the two tokens, sorted ascending by address
    Currency currency1;
    uint24   fee;         // Ascnt pools: LPFeeLibrary.DYNAMIC_FEE_FLAG = 0x800000
    int24    tickSpacing; // 10 on volatile pairs, 1 on pegged pairs
    IHooks   hooks;       // the Ascnt SimHook address for this pool
}

What's specific to an Ascnt Pool:

  • fee is the dynamic-fee flag, 0x800000 (LPFeeLibrary.DYNAMIC_FEE_FLAG) — not a numeric tier. The fee is computed by the hook in beforeSwap; the flag tells v4-core to honour the hook's override.
  • hooks is the SimHook contract — one hook serves every Ascnt pool, with per-pool configuration set at launch. Address and Pool IDs are in Smart contracts.
  • tickSpacing is 10 on volatile pairs and 1 on pegged pairs (stable/stable, gold/gold). Read it from the subgraph rather than assuming.

PoolId

The PoolId is the keccak256 of the ABI-encoded PoolKey:

PoolId poolId = poolKey.toId();   // == keccak256(abi.encode(poolKey))

The quickest way to obtain both is the subgraph — see Read pool data; it returns every pool's identifiers directly, so you don't have to hand-assemble a PoolKey.

Verify it's genuine

Before pointing real funds at a hook address, resolve it from the root — the canonical AscntGovernance at 0x7a669Dc45A5720074B140754254AFd308B638341 (see Smart contracts) — rather than asking the hook about itself:

AscntGovernance gov = AscntGovernance(0x7a669Dc45A5720074B140754254AFd308B638341);
gov.isCanonicalHook(hook);            // true  — deployed by the protocol through its factory
gov.isCanonicalHookDeprecated(hook);  // false — not superseded / sunset
gov.isAddLiquidityBlocked(hook);      // false — deposits not paused, protocol-wide or for this hook

The hook-side views hook.isVerified(), hook.isDeprecated() and hook.governance() are self-attestations — an impostor contract can hardcode them — so they only mean something once you've checked hook.governance() against the canonical address. When indexing, filter HookDeployed / HookDeprecationChanged events by the canonical factory's emitter address, never by event signature alone. The subgraph mirrors the same flags as Hook.deprecated and Hook.addLiquidityPaused.

Deprecation is an advisory retirement signal: it doesn't stop a pool, and a deprecated hook's pools stay open for withdrawals. If a hook is unsafe for deposits, governance pauses new liquidity on it, so an integrator that checks the pause flag needs no extra step.

Interact

It's a standard v4 pool, so you use the normal contracts and the v4 SDK you already know:

  • Liquidity — add, remove, or modify positions through the v4 PositionManager (modifyLiquidities), exactly as on any v4 pool. Two contract-level differences: adds are blocked while a pause flag is set, and a remove reverts with JitLockActive if the position is still inside its JIT block-lock window — two blocks on every current pool. A zero-liquidity fee poke is never blocked. The lock is keyed on the v4 position key and re-arms on every add, so a contract that pools users through one position shares one lock clock — give each user their own salt.
  • Swaps — route through any v4-compatible router or aggregator that respects the hook's fee override; the hook returns the per-swap fee via the override-fee flag in beforeSwap. No special routing is required.

Read pool data

If your strategy reacts to the same signals the hook uses, read them rather than recomputing.

On-chain: the hook exposes per-pool poolConfig (the immutable fee parameters) and poolData (runtime state: cumulative price impact, signed by direction, and the last-swap timestamp). Source and ABIs: github.com/ascntlabs/v1-core.

Subgraph: the Ascnt subgraph indexes every pool, its config, and per-swap state — the easiest way to discover pools and read live state without running a node. Query it through The Graph's gateway with a free API key from The Graph Studio:

https://gateway.thegraph.com/api/{api-key}/subgraphs/id/GBgiXocG8wbK89EwemUN37Ah7sqDwVUDwmXhi48AFJPL

Every live Ascnt pool, with identifiers and config in one call (the subgraph also indexes benchmark pools, so filter on isAscntPool):

query LivePools {
  pools(where: { isAscntPool: true }) {
    id              # the PoolId
    token0 { id symbol }
    token1 { id symbol }
    feeTier
    tickSpacing
    hooks           # the SimHook address — the PoolKey `hooks` field
    dynamicFeePips  # the fee the last swap paid
    cumPriceImpact  # the running imbalance, signed by direction
    minFee          # immutable pool config, set once at launch:
    maxMinFee       #   base-fee floor and ceiling,
    maxFee          #   hard cap on any quote,
    timeDecayLength #   seconds for the imbalance to decay,
    jitLockBlocks   #   the withdrawal lock
  }
}

Entities you can query:

EntityWhat it holds
PoolPoolId (id), token0/token1, feeTier, tickSpacing, hooks, latest sqrtPrice, dynamicFeePips, cumPriceImpact, the immutable config (minFee, maxMinFee, maxFee, timeDecayLength, jitLockBlocks, kPips, cPips) and volume/TVL aggregates.
HookPer hook: deprecated, addLiquidityPaused, and the deploying factory.
SwapOne row per swap with tx metadata and the full hook telemetry: pre-swap price, estimatedPriceImpact, decayedCumPriceImpact, the charged dynamicFeePips, and the realised priceImpact / cumPriceImpact.
ModifyLiquidityEvery add/remove with amounts and tick range.
PoolDayData / PoolHourDataTime-bucketed volume, fees, and TVL per pool.

On this page