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 tomaxPerSidenon-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.marketState()(andstateExpiresAt()ifUnwindOnly) to avoid quoting when halted.RUNG_DENOM()andPRICE_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
maxRungto the furthest rung needed
minQuotePerRung
Minimum quote value per rung to consider (set to 0 to disable). Rungs with total quote value below this threshold are skipped, which can avoid dust-heavy traversal.
deadline
Set a short deadline to reduce the risk of stale offchain quotes being executed after market conditions have changed.
deadline == 0disables 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 withPRICE_SIGFIGS). - Buy target in & sell exact out: the check is against
quoteIn/quoteOutdirectly.
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.
The official Canonic public MAOBPreviewer deployments are listed in Contract Deployments.
For production integrations, prefer those verified deployments unless you intentionally want to operate your own copy.
Each function has a maxRung overload; the version without maxRung traverses all rungs
(maxRung = rungCount - 1).
previewBuyBaseExactOut(maob, baseAmount, maxQuoteIn, maxRung, minQuotePerRung)->(quoteUsed, baseFeePaid, baseOut)previewBuyBaseTargetIn(maob, quoteIn, minBaseOut, maxRung, minQuotePerRung)->(baseOut, baseFeePaid, quoteUsed)previewSellBaseTargetIn(maob, baseAmount, minQuoteOut, maxRung, minQuotePerRung)->(quoteOut, quoteFeePaid, baseUsed)previewSellBaseExactOut(maob, quoteOut, maxBaseIn, maxRung, minQuotePerRung)->(baseUsed, quoteFeePaid, netQuoteOut)
Notes:
baseAmountandquoteInare pre-fee inputs;baseOut/quoteOutoutputs are after fee.- For
previewSellBaseExactOut,quoteOutis net (after fee); the previewer computes the gross quote required and then applies fees. - Previewer checks
marketState(halts only), oracle validity (updatedAt != 0), andminQuoteTakerthe same way MAOB does; per-leg staleness is enforced inside the OracleAdapter. - The previewer is shared per chain. Pass the target MAOB market address as the
maobargument when quoting.
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.