CanonicCanonic Docs
Documentation

CLP Architecture

Overview

The Canonic Liquidity Provider (CLP) contract is an ERC-20 vault token that represents shares in a pooled base token/quote token inventory and deploys that liquidity into MAOB through an operator.

Core responsibilities

  • Liquidity pooling: accept base tokens and quote tokens, mint vault shares, and track proportional ownership.
  • Protocol liquidity: manage pooled protocol liquidity.
  • Liquidity safety: claim, withdraw, and cancel orders to satisfy withdrawals under stress.
  • Realtime accounting: expose a full balance view across free, withdrawable, unfilled, and unclaimed states.

Engineering highlights

  • Ratio-preserving minting: deposits are adjusted to the vault's current balance ratio to avoid skewed inventory.
  • Transfer-delta accounting: deposit logic measures actual tokens received to support fee-on-transfer tokens.
  • Share-based withdrawal fees: a configurable fee burns shares, benefiting remaining LPs by reducing supply.
  • Deterministic liquidity rescue: withdrawals trigger a structured sequence of claim, withdraw, and cancel steps.
  • Bounded order tracking: MAX_ACTIVE_ORDERS = 64 keeps operator state bounded and auditable.
  • No oracle dependency: the vault relies on MAOB state and internal accounting, reducing exposure to oracle manipulation risk.

Architecture at a glance

  • MAOB binding: vault is tied to a single MAOB instance with matching base tokens and quote tokens.
  • Access control: DEFAULT_ADMIN_ROLE for configuration and OPERATOR_ROLE for order operations.
  • Active order registry: activeOrderIds tracks MAOB orders, pruned as orders settle or cancel.
  • Unlimited allowances: base tokens and quote tokens are approved to MAOB at deployment for efficient order placement.

Vault lifecycle

Deposits (dual-asset minting)

Users deposit base tokens and quote tokens via:

  • depositDual(baseAmountDesired, quoteAmountDesired, baseMin, quoteMin)

Mechanics:

  • Initial deposit gate: only admin/operator can seed the vault when totalSupply == 0.
  • Optimal ratio: subsequent deposits are adjusted to the current totalBase:totalQuote ratio.
  • Slippage guards: baseMin and quoteMin are enforced for non-initial deposits.
  • Share minting:
    • initial: sqrt(baseTokenAmount * quoteTokenAmount) - MINIMUM_LIQUIDITY, with MINIMUM_LIQUIDITY minted to the vault
    • ongoing: min(baseDeposit * supply / totalBase, quoteDeposit * supply / totalQuote)

Withdrawals (dual-asset burning)

Users burn shares and receive base tokens and quote tokens via:

  • withdrawDual(shares, baseMin, quoteMin)

Mechanics:

  • Withdrawal fee: withdrawalFeeBps (capped by MAX_WITHDRAWAL_FEE_BPS) burns shares.
  • Cooldown: optional withdrawalCooldown blocks rapid repeat withdrawals.
  • Slippage guards: baseMin and quoteMin must be met.
  • Liquidity guarantee: _ensureLiquidity enforces available base tokens and quote tokens before settlement.

Operator flows

Deploy liquidity to MAOB

  • placeOrders(withdrawOrders, balanceOrders):
    • withdrawOrders re-quotes MAOB withdrawable balances via maob.requoteFromWithdrawable
    • balanceOrders posts new liquidity via maob.addLiquidityBatch

Orders are appended to activeOrderIds and emitted in TopUp(baseUsed, quoteUsed, orderCount).

Claim and cancel

  • claimOrders(orderIds) and claimActiveOrders(startIndex, batchSize) pull fills into the vault.
  • cancelOrders(orderIds, withdrawAfter) claims then cancels any remaining active orders.
  • exitAndWithdrawAll() is the emergency path to claim, cancel, withdraw, and close deposits.

Instant Withdrawals

Withdrawals may require liquidity locked inside MAOB. _ensureLiquidity uses a deterministic sequence:

  1. Claim all MAOB orders.
  2. Withdraw MAOB withdrawable balances into the vault.
  3. Cancel outermost orders until base tokens and quote tokens are sufficient.

This design prioritizes user withdrawals while minimizing unnecessary cancellations.

Realtime accounting

getRealtimeBalances() returns a full inventory breakdown:

  • free: base tokens and quote tokens held by the vault
  • withdrawable: base tokens and quote tokens withdrawable from MAOB
  • unfilled: base tokens and quote tokens still resting in MAOB orders
  • unclaimed: base tokens and quote tokens claimable from MAOB fills

These totals drive deposit ratios and withdrawal calculations, keeping share pricing consistent.