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.takerPaused()to avoid quoting when takers are paused.maxStaleSeconds()to mirror MAOB's oracle staleness policy (if non-zero).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
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.
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:
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
takerPaused,maxStaleSeconds(oracle staleness), andminQuoteTakerthe 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.