State transitions
Think of a pool lifecycle as a sequence of explicit transitions. Here is the “happy path” plus control paths.
Pool creation
A. init_pool
Creates:
pool PDA (state)
lp_mint
registry PDA
Inputs:
base_mint, quote_mint
bin_step_bps
initial_price_q64_64
fee_config (FeeConfig struct)
Emits:
PoolInitialised
B. init_pool_vaults
Creates and attaches the SPL token accounts:
base_vault, quote_vault
creator_fee_vault, holders_fee_vault, nft_fee_vault
After this step, the pool has somewhere to hold liquidity and fees.
Bin provisioning
create_liquidity_bin
Creates a bin PDA at a specific index with bounds and optional analytics liquidity.
Emits:
LiquidityBinCreated
This is typically done by admin (or a pool operator workflow) so the pool has a known bin lattice.
User deposits and LP shares
deposit_into_bins
Depositor provides base and/or quote into chosen bin indices.
Funds move from depositor_base/depositor_quote into base_vault/quote_vault.
LP shares are minted to depositor_lp.
Emits:
LiquidityDeposited
And bin updates via BinLiquidityUpdated
Conceptually:
Swaps
swap
User pays amount_in from user_source.
Pool routes through bins (via SwapRoute.bin_indices).
User receives output to user_destination.
Fees are split during the swap into:
creator_fee_vault
holders_fee_vault
nft_fee_vault
Reserves update per bin traversal.
Emits:
SwapExecuted
FeesDistributed
BinLiquidityUpdated
Slippage safety:
min_amount_out enforced
Error SlippageExceeded if protection fails.
Withdrawals
User withdrawal: withdraw_user
Burns LP shares from user_lp.
Returns pro-rata base/quote from pool vaults to user_base and user_quote.
Enforces lock rules if liquidity_lock exists and is still active.
Emits:
LiquidityWithdrawnUser
Admin-only withdrawal: withdraw_liquidity
Burns shares from admin_lp and moves assets to admin_base/admin_quote.
This is labeled “legacy/admin-only withdrawal” in the IDL and should be tightly governed, especially for permissioned pools.
Emits:
LiquidityWithdrawnAdmin
Liquidity locking
lock_liquidity
Moves LP tokens from user_lp into escrow_lp (owned by pool PDA).
Writes lock metadata to liquidity_lock PDA (amount + lock_end).
Emits:
LiquidityLocked
This creates a hard on-chain rule: locked LP cannot be withdrawn until the lock expires (error 6034).
Fee claiming and distribution
claim_protocol_fees
Withdraws from fee vaults into destination accounts:
creator_fee_vault -> creator_destination
holders_fee_vault -> holders_destination
nft_fee_vault -> nft_destination
Arguments are explicit amounts:
This design is intentionally simple: the program holds fees in vaults and a designated authority triggers withdrawals to downstream distributors (creator treasury, holder rewards distributor, NFT rewards distributor).
Governance and safety controls
Admin rotation
update_admin changes pool.admin
Emits AdminUpdated
Authorities
update_authorities updates:
config_authority
pause_guardian
fee_withdraw_authority
Emits AuthoritiesUpdated
Fee config updates
update_fee_config updates the fee configuration fields
Emits FeeConfigUpdated
Pausing
set_pause toggles pool paused state
set_pause_bits sets a bitmask (guardian-only) for granular disabling (swap/deposit/withdraw)
Last updated