Skip to Content
Stacks Pools

Contracts

Reference for the Zest Protocol concentrated liquidity contracts on Stacks mainnet: their addresses, the live pools, and the pool, router, LP token and governance functions.

Deployed Contracts

Zest Protocol CLMM is live on Stacks mainnet. All contracts are deployed by SP2NK9P261ZN3ZG2M1DS68PCJCRDFZVFMPYA6ZEST.

ContractRole
clmm-pool-v1Holds every pool and bin, executes swaps, deposits and withdrawals, and keeps protocol fees
clmm-router-v1Stateless batching and routing on top of the pool: multi-bin and multi-pool swaps, fill-or-kill, batched deposits
clmm-lp-token-v1SIP-013 bin shares, one token id per bin
executor-daoExecutes governance proposals
operators2-of-3 multisig that approves proposals

All pools live in one pool contract and are identified by a numeric pool-id. The router holds no state and no funds: every call executes as the transaction sender.

Pools on Mainnet

Pool IDPair (X / Y)Bin widthSwap feeLP share of the fee
1STX / USDCx1%0.30% each way80%
2ZEST / STX1%1% each way100%

The pools use these token contracts:

TokenContract
STXSP1A27KFY4XERQCCRCARCYD1CC5N7M6688BSYADJ7.wstx, registered as a native STX token, so the pool moves STX itself
USDCxSP120SBRBQJ00MCWS7TM5R8WJNTTKD5K0HFRC2CNE.usdcx
ZESTSP1A27KFY4XERQCCRCARCYD1CC5N7M6688BSYADJ7.zest-token

Governance can change a pool’s fees and state by proposal, so get-pool is the source for a pool’s current settings.

Units

  • Prices in function arguments are WAD: 10¹⁸ is a price of 1 token X per token Y, in raw base units.
  • Fee rates, LP fee shares, discounts and percentages are in units of 10⁸: u100000000 is 100%.
  • Bin steps are basis points: u100, u500, u1000 or u2000.
  • Deadlines are Unix seconds, compared with the timestamp of the block the transaction is mined in.

Integration Rules

  • Pass the pool’s own tokens. Every call takes the two token contracts as traits, and they must be the pool’s token X and token Y.
  • Order ticks by price. Ascending for X to Y, descending for Y to X.
  • Set real limits. Pass a price limit, a minimum output from the quote and a short deadline on every swap.
  • Use post-conditions in deny mode. Account for every token that leaves the signer.
  • Redeem shares directly. The pool redeems shares only for an owner that calls it directly. Withdrawals cannot be batched through another contract.
  • Find positions from events. The LP token keeps no per-owner list of token ids; index its sft_mint, sft_burn and sft_transfer events.

clmm-pool-v1

Purpose: Pools, bins, swaps, positions and protocol fees for every Zest Protocol CLMM pool.

List of Core Functions

Positions

  • add-to-position: Deposit into one bin and mint its shares
  • reduce-position: Withdraw a percentage of the caller’s shares in one bin
  • reduce-positions: Withdraw from up to 64 bins in one call

Swaps

  • swap-x-for-y-ioc, swap-y-for-x-ioc: Swap inside one bin, immediate-or-cancel
  • swap-x-for-y-route, swap-y-for-x-route: Swap across up to 32 bins of one pool (also reached through the router)

Queries

  • get-pool: A pool’s tokens, bin step, fees, state and depositor
  • get-pool-id: The public pool for a token pair and bin step
  • get-pool-count: Number of pools created
  • get-bin-state: A bin’s reserves, share supply and liquidity
  • get-pool-balances: A bin’s stored reserves and supply
  • get-bin-price: A bin’s current price (WAD)
  • get-pool-fees: A pool’s accrued protocol fees
  • get-fee-rates, get-fee-discount: The rates and discount an address has in a pool
  • get-liquidity-token-id, parse-liquidity-token-id: Convert between a bin and its share token id
  • is-native-stx-token, is-listed-token: Token registration state
  • quote-swap-x-for-y, quote-swap-y-for-x (and -as variants): Single-bin swap quotes
  • quote-add-to-position (and -as variant): Deposit quote
  • simulate-swap-x-for-y, simulate-swap-y-for-x, simulate-deposit: Quotes against any reserves

Governance

  • create-pool, create-private-pool: List a pool
  • set-pool-depositor: Reassign a private pool to a new depositor
  • update-pool-fee: Change fee rates and the LP fee share
  • set-fee-discount: Give an address a discount on a public pool
  • set-pool-status: Pause or sunset a pool
  • set-native-stx-token: Register a token that moves native STX
  • claim-fees: Pay out accrued protocol fees

Function Parameters

add-to-position

Deposit exact amounts of X and Y into one bin and mint its shares. Fails while the pool is paused or sunset. In a private pool only the depositor can call it.

ParameterTypeDescription
token-x-trait<ft-trait>The pool’s token X
token-y-trait<ft-trait>The pool’s token Y
pool-iduintPool to deposit into
tickintBin to deposit into
dxuintAmount of X to deposit
dyuintAmount of Y to deposit
min-priceuintLowest bin price after the deposit to accept (WAD)
max-priceuintHighest bin price after the deposit to accept (WAD)
min-sharesuintFewest shares to accept

Returns: (response { dx: uint, dy: uint, shares: uint, fee-x: uint, fee-y: uint } uint). Amounts deposited, shares minted and the implicit swap fee charged


reduce-position

Burn a percentage of the caller’s shares in one bin and pay out the matching reserves. Works in every pool state. The caller must call the pool directly.

ParameterTypeDescription
token-x-trait<ft-trait>The pool’s token X
token-y-trait<ft-trait>The pool’s token Y
pool-iduintPool to withdraw from
tickintBin to withdraw from
percentuintShare of the caller’s shares to burn (10⁸ = 100%)
min-dxuintFewest X tokens to accept
min-dyuintFewest Y tokens to accept

Returns: (response { shares: uint, dx: uint, dy: uint } uint). Shares burned and tokens paid out


reduce-positions

Withdraw from up to 64 bins of one pool and pay each token once. Bins whose burn rounds to zero are skipped. Works in every pool state. The caller must call the pool directly.

ParameterTypeDescription
token-x-trait<ft-trait>The pool’s token X
token-y-trait<ft-trait>The pool’s token Y
pool-iduintPool to withdraw from
items(list 64 { tick: int, percent: uint })Bins and percentages to burn
min-dxuintFewest X tokens in total
min-dyuintFewest Y tokens in total

Returns: (response { shares: uint, dx: uint, dy: uint } uint). Total shares burned and tokens paid out


swap-x-for-y-ioc

Sell X for Y inside one bin. Spends as much of dx as fits before the price reaches max-price or the bin runs out of Y. Fails while paused.

ParameterTypeDescription
token-x-trait<ft-trait>The pool’s token X
token-y-trait<ft-trait>The pool’s token Y
pool-iduintPool to trade in
tickintBin to trade in
dxuintMost X to spend, fee included
max-priceuintHighest marginal price to trade at (WAD)
min-dyuintFewest Y tokens to accept
deadlineuintUnix seconds; reverts in a block mined after this

Returns: (response { dx: uint, dy: uint, fee: uint } uint). X spent, Y received and the fee charged

swap-y-for-x-ioc is the mirror image: it takes dy, min-price and min-dx.


get-pool

ParameterTypeDescription
pool-iduintPool to read

Returns: (optional { token-x, token-y, bin-step, fee-rate-x, fee-rate-y, fee-rebate, sunset, paused, native-x, native-y, depositor, discounts }). depositor is none for a public pool; discounts counts the pool’s partner discounts


get-bin-state

ParameterTypeDescription
pool-iduintPool to read
tickintBin to read

Returns: (response { balance-x: uint, balance-y: uint, total-supply: uint, liquidity: uint } uint). The bin’s reserves, share supply and liquidity in one read


clmm-router-v1

Purpose: Batching and routing on top of clmm-pool-v1. Stateless; every call executes as the transaction sender.

List of Core Functions

  • add-to-positions-many: Deposit into up to 100 bins of one pool
  • swap-x-for-y, swap-y-for-x: Swap across up to 32 bins of one pool
  • swap-x-for-y-fok, swap-y-for-x-fok: Single-bin swap that must spend the whole input
  • swap-routes: Swap through up to 9 pools in sequence

Function Parameters

swap-x-for-y

Sell X for Y across the listed bins of one pool, in strictly ascending tick order.

ParameterTypeDescription
token-x-trait<ft-trait>The pool’s token X
token-y-trait<ft-trait>The pool’s token Y
pool-iduintPool to trade in
dxuintX to spend, fee included
max-priceuintHighest marginal price to trade at (WAD)
ticks(list 32 int)Bins to walk, strictly ascending
min-dyuintFewest Y tokens to accept in total
allow-partial-fillboolFalse to revert unless all of dx is spent
deadlineuintUnix seconds; reverts in a block mined after this

Returns: (response { dx: uint, dy: uint, fee: uint } uint). X spent, Y received and the fee charged

swap-y-for-x is the mirror image: it takes dy, min-price, strictly descending ticks and min-dx.


swap-routes

Swap through a sequence of pools. Every hop must fill completely.

ParameterTypeDescription
tokens(list 10 <ft-trait>)The path: the first token is sold, the last bought
routes(list 9 { pool-id: uint, ticks: (list 32 int), x-for-y: bool })One entry per hop, with its bins and direction
token-inuintAmount of the first token to sell
min-token-outuintFewest of the last token to accept
deadlineuintUnix seconds; applies to every hop

Returns: (response { token-in: uint, token-out: uint } uint). Amount sold and amount received


add-to-positions-many

Deposit into up to 100 bins of one pool in one transaction. Each entry is passed to add-to-position with its own amounts and bounds.

ParameterTypeDescription
token-x-trait<ft-trait>The pool’s token X
token-y-trait<ft-trait>The pool’s token Y
pool-iduintPool to deposit into
positions(list 100 { tick: int, max-x: uint, max-y: uint, min-price: uint, max-price: uint, min-shares: uint })One entry per bin

Returns: (response (list 100 { dx, dy, shares, fee-x, fee-y }) uint). One result per bin


clmm-lp-token-v1

Purpose: SIP-013 semi-fungible bin shares. Token id = pool-id × 2⁶⁴ + (tick + 2³²); one id per bin. Name Zest CLMM LP, symbol ZCLMM-LP, no decimals.

  • transfer, transfer-memo: Move shares; the sender must be the immediate caller
  • transfer-many, transfer-many-memo: Move up to 200 share balances at once
  • get-balance, get-overall-balance: Shares an owner holds in one bin, or across all bins
  • get-total-supply, get-overall-supply: Shares of one bin, or of all bins
  • mint, burn: Callable only by clmm-pool-v1

Governance Contracts

  • executor-dao: Executes proposals and records its extensions. Constructed once, by a direct call from the deployer, with the bootstrap proposal.
  • operators: m-of-n multisig, 2-of-3 on mainnet. approve records an operator’s approval of a proposal and executes it at the threshold. is-operator, get-threshold, get-operator-count, get-epoch and get-proposal read its state.

See Governance for what proposals can and cannot do.

Last updated on