Gully Core

Build

Router and swaps

The swap box finds the best price across Gully Core pools and other venues on the chain. Put it on your page with one line of HTML, or quote and swap from your own code. Everything here trades on the chains where Gully Core is deployed. Gully Chain Testnet trades testnet tokens. See Chains.

One line: the swap box

Paste this into any page. It is the same swap box as the Swap screen, with its own wallet connect. Nothing to install, no key, no React.

html
<iframe src="https://app.gullycore.xyz/embed/swap" title="Swap on Gully Core" width="420" height="640" style="border:0"></iframe>

It opens on a pool with liquidity. To open on your own pair, add ?in=0x…&out=0x… to the address. The zero address is the native coin. A pair with no pool is ignored. theme=light or theme=dark sets the look. The same two addresses work on the Swap screen, so a link can open the app on your market.

The API needs no package and no key to read. Each pool comes back with its full key, its live price and its fee: GET /v1/chains/<chainId>/pools?limit=50&offset=0.

Best price

Every quote compares Gully Core's own pools with the other venues the router covers on that chain, after gas, and shows where the trade will fill. A trade on a Gully Core pool goes through the UniversalRouter. A trade on another venue goes through GullyCoreFillRouter, which fills it there in the same transaction and returns the output to you.

The same swap box is on Trade, on every token page, on every hosted DEX and in the widget.

What a trade costs

PartWho sets itAmount
Pool feeThe pool (or its hook, on a dynamic-fee pool)Shown on the quote
Core protocol feeGovernance, per poolat most 0.4%
Routing feeGullyCoreFillRouter, on fills at another venue onlyread from the contract
On a Gully Core poolGullyCoreFillRouter0
Launch fee and creator taxThe launch, inside the guard's limitsSee Launch a token

The routing fee is read from the contract and is zero on a Gully Core pool so that a Gully Core pool is the cheaper venue when the prices are equal. It is a governed value inside an immutable cap. A decrease is immediate, and nothing applies to a quote already given. The cap and notice period are read from GullyCoreFillRouter (feeBps(), maxFeeBps(), feeNoticeSeconds()).

The fee is charged on what the trade actually spends, never on the output, so an exact-output trade does not fill worse than quoted. Price impact and the fee are shown as separate numbers.

What you pay as a builder

Build on Gully Core from outside Gully Labs and Gully takes a flat 0.30% of every trade on the pools you create, and nothing else. There is no kit split and no share of creator tax. You and your launchpad decide how the rest is shared.

WhatGully takes
Every trade on your pools0.30%, set by the fee controller on the shared core
Kit split on your launchesNone
Creator tax on your launchesNone
The most the fee can ever be0.40%, the cap in the core. The Safe may lower a pool's fee, never raise it past the cap

Gully Core is built on PancakeSwap Infinity's audited core. More on the fee model in Fees.

Approvals and Permit2

  • Once per token: an ERC-20 approval of Permit2, the canonical permit contract at the same address on every chain.
  • Each swap: a signature that authorises that swap's amount for that router, with a deadline. No new on-chain approval.
  • Selling the native coin needs no approval at all.

Paying with the native coin

You can pay with, or receive, the native coin in a pool quoted in its wrapped form (WHYPE, WBNB, WETH). The router wraps and unwraps inside the same transaction. You never hold the wrapped token unless you choose it. The native coin is currency 0x0000…0000 and the wrapped native is an ERC-20. A pool in one is not a pool in the other.

On Anubis the gas coin pays gas only and cannot be sent as a value, so pools there quote in DAI.

Quote

A quote runs the real swap against current state, the pool's hook included, and reverts with the answer. Call it with eth_call. It costs nothing and sends nothing.

getSlot0(poolId) on the pool manager gives a pool's spot state (CL: sqrtPriceX96, tick, protocolFee, lpFee. Bin: activeId, protocolFee, lpFee). For an amount, quote through CLQuoter or BinQuoter. The quoter runs the real swap, hook included, and reverts with the result, so the answer already accounts for whatever the pool's hook takes.

Swap through the UniversalRouter

Swaps on Gully Core pools execute through the UniversalRouter: one INFI_SWAP command carrying the swap action, a settle of the input from the caller and a take of the output. Encode the swap, simulate the exact bytes, then send them.

  • The router pulls ERC-20 input through Permit2. The caller approves the token to Permit2 once and grants the router an allowance in Permit2, or signs a permit the plan applies first.
  • Native input is sent as value.
  • The SDK's buildSwapCall also encodes multi-hop routes, Bin pools, wrap and unwrap of the native coin, and an integrator fee.
  • The SDK's verifySwapCalldata decodes router calldata from any source and refuses anything but the swap you asked for.

Router API

Gully Core's Router API quotes across Gully Core pools and the third-party venues it covers on a chain and returns the calldata to sign. A route through a Gully Core pool pays no routing fee. A fill at another venue goes through GullyCoreFillRouter, whose fee is read from the contract on every quote and shown on its own line. It has its own rate limit. Anonymous callers get a small per-IP allowance, and a server sends an API key with the router:quote scope in the X-API-Key header. A chain the router does not serve answers 404.

MethodPathReturns
GET/v1/chains/:chainId/quote?tokenIn=&tokenOut=&amount=&slippageBps=The best route, amount out, minimum out, price impact, gas and the routing fee
POST/v1/chains/:chainId/swapThe transaction to sign. Nothing is signed or sent
POST/v1/chains/:chainId/simulateA transaction simulated, with the fill it would make
GET/v1/chains/:chainId/sourcesThe venues the router covers on the chain
GET/v1/chains/:chainId/fee-configThe routing fee in force, its cap and notice, read from the contract

Trading a launch

  • The trade fee and any creator tax are taken in the quote currency on buys and sells, and shown on the quote.
  • In a launch's first seconds the fee is high and falling: the anti-snipe fee decays over at least 60 seconds.
  • While a maximum buy is in force, larger buys and exact-output buys are refused.
  • A buy that would run past the end of a CL launch range reverts (SwapNotFilled). The app sizes buys from a quote.

Details on Launch a token.

What is checked before you sign

  • Every transaction is simulated against the current block first. One that would revert is not offered for signing.
  • When a route comes from the router API, the app decodes the returned calldata and refuses it unless it is exactly the swap you asked for: your tokens, at most your amount in, the output only to you, your minimum and deadline (verifySwapCalldata in the SDK).
  • The minimum you receive is the quote less your slippage tolerance. A fill below it reverts.

What to handle in an integration

  • Hooks change the cost of a trade. A pool's hook is poolKey.hooks. Always price a hooked pool with the quoter, never from getSlot0 and the fee alone.
  • Launch pools. A launch pool's guard charges its trade fee and any creator tax itself, in the pool's quote currency, as a hook delta. The pool's own LP fee understates the cost. Read the fee from the guard (currentFeeParts(poolId), currentTaxRates(poolId)) or from the API's launchFee and launchTax fields.
  • Dynamic-fee pools. A fee of 0x800000 in the key means the hook sets the LP fee. Quote, do not compute.
  • No fee-on-transfer or rebasing tokens. The Vault credits what it is told was paid. A token that delivers less leaves the settlement short.

Wrong or missing? Tell us at @Gully_Labs.