CanonicCanonic Docs
Documentation

Read-only Quoting

Overview

MAOB is designed to be quoted offchain using a combination of:

  • oracle mid price (getMidPrice)
  • rung configuration (getRungs, rungCount)
  • live liquidity depth (getDepth, getRungState)
  • per-order claimability (previewOrder) for maker UX

This page describes practical patterns for quoting and choosing taker guardrails.

Reading market state

Mid price

Use:

  • getMidPrice() -> (price, precision, updatedAt)

If updatedAt is stale relative to your own policies, you should refuse to quote.

Rungs

Use:

  • getRungs() to read the configured bps offsets.
  • Interpret bps as 0.1 bps units (denom 100_000).

Depth

Use:

  • getDepth(maxPerSide) to fetch up to maxPerSide non-zero rungs per side.

Returns:

  • ask rung bps values + volumes (base token units)
  • bid rung bps values + volumes (quote token units)

This is a “summary” view (closest rungs first by rung index scan) and is often enough for UI depth and rough quoting.

Per-rung detailed state

Use:

  • getRungState(rung) to read volumes and generation/cumulative fill values.
  • getLastSegment(rung, isAsk) for debugging or advanced inspection.

Other parameters to fetch

For accurate quotes and guardrails, you will also want:

  • takerFee() + FEE_DENOM() to compute taker fees.
  • minQuoteTaker() for minimum notional checks.
  • takerPaused() to avoid quoting when takers are paused.
  • maxStaleSeconds() to mirror MAOB's oracle staleness policy (if non-zero).
  • RUNG_DENOM() and PRICE_SIGFIGS() to match price math and rounding.

Choosing taker guardrails

maxRung

maxRung controls how far from the midpoint you will cross. A common approach:

  • choose a rung limit based on acceptable slippage from mid
  • quote a price impact using depth
  • set maxRung to the furthest rung needed

deadline

Set a short deadline to reduce the risk of stale offchain quotes being executed after market conditions have changed.

  • deadline == 0 disables checks (generally not recommended for UI trading flows)

Slippage parameters

  • For buy exact out: set maxQuoteIn
  • For buy target in: set minBaseOut
  • For sell target in: set minQuoteOut
  • For sell exact out: set maxBaseIn

Minimum quote checks (minQuoteTaker)

MAOB enforces a minimum quote notional. For quoting:

  • Buy exact out & sell target in: the check is against the midpoint value of baseAmount (rounded with PRICE_SIGFIGS).
  • Buy target in & sell exact out: the check is against quoteIn / quoteOut directly.

Onchain previewing (MAOBPreviewer)

MAOBPreviewer is a stateless view helper that simulates MAOB taker fills against live state. It mirrors MAOB rounding, remainder carry, taker fees, and guardrails. Use it via eth_call to get an exact quote before submitting a transaction, or to validate an offchain simulator.

Each function has a maxRung overload; the version without maxRung traverses all rungs (maxRung = rungCount - 1).

  • previewBuyBaseExactOut(maob, baseAmount, maxQuoteIn, maxRung) -> (quoteUsed, baseFeePaid, baseOut)
  • previewBuyBaseTargetIn(maob, quoteIn, minBaseOut, maxRung) -> (baseOut, baseFeePaid, quoteUsed)
  • previewSellBaseTargetIn(maob, baseAmount, minQuoteOut, maxRung) -> (quoteOut, quoteFeePaid, baseUsed)
  • previewSellBaseExactOut(maob, quoteOut, maxBaseIn, maxRung) -> (baseUsed, quoteFeePaid, netQuoteOut)

Notes:

  • baseAmount and quoteIn are pre-fee inputs; baseOut / quoteOut outputs are after fee.
  • For previewSellBaseExactOut, quoteOut is net (after fee); the previewer computes the gross quote required and then applies fees.
  • Previewer checks takerPaused, maxStaleSeconds (oracle staleness), and minQuoteTaker the same way MAOB does.

Failure modes to expect (previewer reverts; surface these in UIs):

  • MAOB__InvalidAmount(), MAOB__InvalidRung()
  • MAOB__TakerPaused()
  • MAOB__OraclePriceMissing(), MAOB__OracleStale(), MAOB__OracleOutOfRange()
  • MAOB__InsufficientLiquidity()
  • MAOB__MaxQuoteExceeded() / MAOB__MaxBaseExceeded()
  • MAOB__MinBaseNotMet() / MAOB__MinQuoteNotMet() / MAOB__QuoteAmountTooLow()

Notes on precision and rounding

MAOB rounds internal priceQ to a fixed significant-figure configuration. This means:

  • exact offchain simulation is possible but must match rounding behavior
  • small trades can be affected by rounding “dust”

The previewer uses getLastSegment(rung, isAsk) to carry per-rung remainder state on the ask side. If you simulate offchain, you must incorporate this remainder logic; otherwise, your quote may be slightly optimistic or pessimistic.

For critical integrations, prefer conservative slippage buffers.