Skip to Content
EntryTokenRegistry & DexAdapter

EntryTokenRegistry and DexAdapter

EntryTokenRegistry is the allowlist + deterministic routing table for multi-token entry.

It enables:

  • Furnace.enterWithToken(tokenIn, amountIn, …): tokenIn -> CLAIM (direct or via WETH)
  • MineCore.takeoverWithToken(tokenIn, amountIn, minEthOut): tokenIn -> WETH -> unwrap -> ETH

Key constraints (v1.0.0):

  • no user-supplied routes
  • allowlist only
  • every hop is validated against allowlisted pools via router.poolFor(…)

Policy split: two registries

v1.0.0 expects two registry instances:

  • FurnaceEntryTokenRegistry
    • tokens allowed for onboarding into the Furnace
  • MineCoreEntryTokenRegistry
    • tokens allowed for takeovers (recommended to start empty or extremely conservative)

Do not wire the same registry into both surfaces.

WETH special-case (required)

WETH is always supported without allowlisting:

  • token configs forbid tokenIn == wrappedNative
  • core entrypoints special-case tokenIn == WETH:
    • MineCore.takeoverWithToken(WETH, amountIn, minEthOut): unwrap 1:1, enforce ethOut >= minEthOut
    • Furnace.enterWithToken(WETH, amountIn,…): unwrap 1:1, then treat as ETH input

RouterConfig

Registry stores global router config:

  • router (v1.0.0 expects DexAdapter)
  • factory (must equal router.defaultFactory())
  • wrappedNative (must equal router.weth())
  • claimToken (must match the immutable ClaimToken)

Important invariant:

  • wrappedNative and claimToken are immutable after first set.

Canonical WETH/CLAIM hop

The registry stores the pinned WETH/CLAIM pool:

  • used for Furnace ETH entry (ETH -> CLAIM)
  • used for token routes that go tokenIn -> WETH -> CLAIM

Per-token TokenConfig

Each allowlisted token has:

  • enabled (gate inside this registry instance)
  • tokenIn -> WETH hop (always required)
  • optional tokenIn -> CLAIM direct hop (Furnace-only)

Route resolution:

  • resolveTakeoverRoute(tokenIn) -> [tokenIn -> WETH]
  • resolveFurnaceRoute(tokenIn) ->
    • [tokenIn -> CLAIM] if directToClaimEnabled
    • else [tokenIn -> WETH, WETH -> CLAIM]

Guardian: disable-only

EntryTokenRegistry has a guardian role for incident response:

  • owner can enable and disable
  • guardian can disable only

This is how the protocol can rapidly remove a problematic token or pool route.

DexAdapter

DexAdapter is the Aerodrome v2 router wrapper.

Why it exists:

  • keeps the immutable core from hard-binding to a specific DEX router forever
  • pins the minimal swap ABI surface used by MineCore and Furnace

Operational model:

  • routing changes ship by redeploying DexAdapter and timelock-updating EntryTokenRegistry.router
  • core contracts freeze their registry address pointers, not the registry’s internal routing table

Token-entry calls require user slippage guards:

  • Furnace: minVeOut
  • MineCore takeoverWithToken: minEthOut

Do not attempt to recreate routing offchain by hand.

Use canonical quote surfaces:

  • Furnace provides built-in view quotes:
    • quoteEnterWithEth
    • quoteEnterWithClaim
    • quoteEnterWithToken
  • MineCore token takeovers use a separate view contract:
    • MineCoreQuoter.quoteTakeoverWithToken(tokenIn, amountIn) -> (ethOut, takeoverPrice)
    • MineCoreQuoter.resolveTakeoverRoute(tokenIn) -> RegistryRoute[]

Why MineCoreQuoter exists:

  • keeps MineCore bytecode smaller (DEX quote + validation lives here)
  • mirrors MineCore’s swap validation:
    • routes are registry-resolved (no user-supplied routes)
    • allowlisted pool must match router.poolFor(...)
    • tokenIn == wrapped native is special-cased (unwrap 1:1)

Agent / UI recipe (token takeovers):

  • quote ethOut for your chosen amountIn
  • choose slippageBps
  • compute minEthOut = ethOut * (10_000 - slippageBps) / 10_000
  • call MineCore.takeoverWithToken(tokenIn, amountIn, minEthOut)

Agent SDK helpers

The TypeScript Agent SDK provides a canonical way to consume these routes and quotes:

  • Spot swap quoting via the protocol’s DexAdapter:
    • quoteDexAmountsOut({ amountIn, routes })
  • Route resolution (allowlisted):
    • resolveMineCoreTakeoverRoute({ tokenIn }) (token -> WETH)
    • resolveFurnaceEntryRoute({ tokenIn }) (token -> CLAIM direct or via WETH)
  • Common spot price helpers:
    • quoteEthToClaim({ ethIn })
    • quoteClaimToEth({ claimIn })
    • quoteEntryTokenToEth({ tokenIn, amountIn })
    • quoteEntryTokenToClaim({ tokenIn, amountIn })

For a “bot-ready” aggregated snapshot (CLAIM spot + all enabled entry tokens), use:

  • getLivePrices({ subgraphUrl, ... })
  • Optional caching / throttling for polling loops: getLivePrices({ subgraphUrl, cache: createLivePricesCache(), ... })
  • CLI: npm -C agents/sdk run example:prices
  • CLI with caching: PRICES_CACHE=1 ... npm -C agents/sdk run example:prices