Direct pools

Quoting pairs no aggregator will route — filing a pool against a trusted factory, creating and seeding it from your own wallet, and the market-risk acknowledgement that gates the whole thing.

6 min readUpdated 4 August 2026admin, liquidity, pools, uniswap, amm, risk

An aggregator finds you a price. It cannot find one for a token nobody has ever listed — your own token, a launch nobody indexes yet, a pair that exists in one pool on one chain. A direct pool is the answer to exactly that case, and it works by quoting a specific AMM pool's own reserves instead of asking anyone.

It is off by default and it takes a Super Admin to switch on, because turning it on is the first time this platform can put your money at risk.

What this is not

The platform does not deploy contracts. A pool is deployed by a factory that was already on the chain — Uniswap's, PancakeSwap's — from a static registry this product ships. The platform also never signs a pool transaction. Creating, approving, seeding and withdrawing are transactions the console renders as calldata and you send from your own wallet. There is no key here for it to use, deliberately: the ecosystem master wallet is your custodial treasury, and seeding a pool from it would move customer-backing capital into a position only a signed withdrawal can reverse.

The five steps

  1. File the pool. Admin → Swap → Liquidity → Pools → Create. Pick the chain, the AMM deployment and the two tokens. The console asks the factory whether the pool already exists: if it does, the row is created with the factory's own address; if it does not, the row is a draft and the create transaction appears on its page.

    1. Lifecycle: draft, active, retired
    2. Freshness, not a badge — a stale pool stops quoting
    3. Open this row for steps 2 to 5: create, verify, acknowledge, seed
  2. Create it, if it does not exist. Open the pool and sign the create step. The address is then read back out of the factory's own PairCreated / PoolCreated event — never from your input, and never from the CREATE2 prediction the console shows you beforehand.

  3. Verify it. The verify button runs eleven checks: bytecode present, the factory round-trip agrees, canonical token order, the fee tier, the tick spacing, decimals, the router's wrapped-native address, depth, and both legs' allowlist status. A pool contract can say anything about itself, so every claim it makes is checked against the factory — which is trusted because it is in a registry the product ships, not because a contract said so.

  4. Read the risk notice and accept it. Six clauses, each ticked individually, then a typed confirmation of the fee tier and the price. See below.

  5. Seed it. Approve both tokens, then add liquidity. Each receipt is read back and recorded from what the chain said.

The acknowledgement, and why it is obstructive

Seeding a pool makes you the liquidity provider on a market your own users trade. That is a change of role, not a change of setting, so the gate is deliberately hard to click through:

  • Six clauses, ticked one at a time. There is no select-all and adding one would defeat the control.
  • A typed confirmation of two numbers — the fee tier and the implied price. A checkbox is muscle memory; those two numbers are your entire income rate and your worst single-transaction loss.
  • The wording is recorded as a hash. If the notice ever changes, every prior acceptance reads as stale and seeding re-blocks until it is read again. An acknowledgement of words nobody currently shows is not an acknowledgement.

Turning off dexPoolRiskAckRequired removes the dialog, never the record: a waiver row is written naming the Super Admin who allowed it, because "who allowed this" has to stay answerable from the position itself.

The first add sets the price

On an empty pair there is nothing to compare against, so the ratio you supply IS the price. Uniswap V2 takes the reserveA == 0 && reserveB == 0 branch: nothing can revert, the minimums are meaningless, and the first arbitrage bot to notice a wrong price takes the difference in the first block, irreversibly.

The console renders the implied price in the largest type on the page in both directions1 MYTKN = 0.20 USDC and 1 USDC = 5 MYTKN are the same fact, and an operator holding the ratio upside down reads one as obviously wrong and the other as fine. When both tokens have an independent price it also compares against it and refuses above dexSeedMaxDeviationBps.

What can go wrong, and what it looks like

The prediction does not match the factory's address

The console shows a CREATE2 prediction before you create a pool. If the factory then emits a different address, verification refuses and leaves the row a draft. This is not a fact about your pool: it means the initCodeHash recorded for that deployment is wrong, so every address this platform would predict on that venue is a stranger's contract. Fix the deployment before verifying anything else on it.

The liquidity went to a platform wallet

If the mint recipient is an ecosystem master wallet, a custodial wallet or a user wallet, the seed is not recorded as an operator position and the market must not be activated. The transaction is already mined and nothing here can undo it — withdraw the liquidity to that wallet and re-seed from one you hold personally. The plan builder refuses to render calldata to such an address in the first place; this second check exists because a plan is not the only way to broadcast a transaction.

The pool shows a liquidity of "—"

The reserves could not be priced in dollars, which is the normal state for your own token before it has an external price anywhere. It is shown as rather than $0 on purpose: the depth floor refuses on an unknown value and would pass a zero it believed.

Your own token is not in Swap after you deployed it

Ecosystem tokens trade on the internal matching engine and have no on-chain pool, so no aggregator can quote them. Making one swappable means creating a pool for it here, seeding it, allowlisting the token, and binding a pair — in that order.

Where seeding locks you out

/api/admin/dex/pool/** is exempt from geo restrictions only through the staff bypass. With the admin bypass off and a full rule on your own country you cannot seed, add to, or withdraw your own liquidity — and the only reachable escape is the geo console itself, which is unconditionally exempt. The pool page shows a warning when the bypass is off, for exactly this reason.