The Quote object
Every field the quote carries, its units, and the rate conversion that is easy to get wrong.
Quote is what QuoteEngine.quote() returns and what every builder takes. Everything an
interface must display is a field here, because a number computed in the interface is a number
nobody can audit afterwards.
Every amount is a bigint in base units. Nothing is converted to a JavaScript number:
2^53 is smaller than the base unit supply of several of these assets.
Identity and amounts
| Field | Type | Meaning |
|---|---|---|
network | string | The network this quote was computed for. |
assetIn, assetOut | AssetRef | The asset references, or the ADA symbol. |
assetInSymbol, assetOutSymbol | string | As the registry names them. |
decimalsIn, decimalsOut | number | Needed to display any amount or the rate. |
amountIn | bigint | The input, in base units. |
amountOut | bigint | What the route delivers at readAt. |
minimumOut | bigint | The number the transaction is held to. |
slippageBps | number | The allowance minimumOut was derived with. |
minimumOut is derived from amountOut by a slippage deduction with a ceiling, so the
on-chain bound is never looser than the quote implies.
The rate
| Field | Type |
|---|---|
rateScaled | bigint |
rateScale | bigint |
rateScaled / rateScale is output base units per input base unit, scaled so it stays exact and
integral. RATE_SCALE is 10^18.
This is not a human readable price. To show a rate, adjust by the two assets' decimal exponents:
displayed = rateScaled / rateScale * 10^(decimalsIn - decimalsOut)Skipping that step produces a number wrong by ten to the difference of the exponents. For a six
decimal asset against a zero decimal one that is a factor of a million. decimalsIn and
decimalsOut are carried on the object for exactly this purpose.
Both front ends use the same formula, so they cannot disagree.
Fees
interface QuoteFees {
lpFeeIn: bigint;
protocolFeeIn: bigint;
venueExecutionLovelace: bigint;
venueExecutionFeeIsWorstCase: boolean;
depositLovelace: bigint;
}| Field | Unit | Meaning |
|---|---|---|
lpFeeIn | Input base units | Pool fees. |
protocolFeeIn | Input base units | The venues' protocol share of those pool fees. |
venueExecutionLovelace | Lovelace | Paid to venue operators or added to pools. Not refundable. |
depositLovelace | Lovelace | Rides with an order and comes back. |
venueExecutionFeeIsWorstCase is the one figure on a quote that can overstate the cost. A
venue that scoops orders in a batch spreads its fee across the batch, so an order scooped alone
pays all of it. Showing that number bare reads as a promise of precision the venue never made.
The aggregate rule: a sum containing one upper bound is itself only an upper bound, so the total is a worst case as soon as any single leg's is. The reduction never turns an uncertain leg into a certain total.
Price impact
priceImpactPips: bigint is the shortfall against the marginal price, in hundredths of a basis
point. Ten to the sixth is one percent.
The reference is the route's own marginal price, read as a closed form off the exact reduction. See Routing.
The route
interface Route {
branches: readonly RouteBranch[];
amountIn: bigint;
amountOut: bigint;
atomicity: RouteAtomicity;
executionClasses: readonly ExecutionClass[];
venueIds: readonly string[];
}Each branch is one path from the input asset to the output asset with its allocation:
interface RouteBranch {
hops: readonly RouteHop[];
amountIn: bigint;
amountOut: bigint;
}Each hop is one pool spend or order:
| Field | Meaning |
|---|---|
venueId, poolOutRef, poolId | Which pool, and the exact UTxO it was decoded from. |
executionClass | Kernel or Commitment. |
assetIn, assetOut | The direction through this pool. |
amountIn, amountOut | In base units of each side. |
lpFee | The pool's own fee, in input base units of this hop. |
protocolFee | The venue's share of that fee. |
extraLovelace | Lovelace this hop adds beyond the network fee. |
risk | This pool's PoolRiskFlags. |
atomicity is "atomic", "single-order" or "needs-settlement". See Execution
classes.
The baseline and the saving
interface Baseline {
exists: boolean;
venueId: string | null;
poolOutRef: string | null;
amountOut: bigint | null;
reason: string | null;
}| Field | Type | Meaning |
|---|---|---|
savingAbsolute | bigint | amountOut minus the baseline output. Zero when no baseline exists. |
savingBps | bigint | The same saving in basis points of the baseline, floored. |
routingBeatsDirect | boolean | False when the baseline is at least as good, and false when no baseline exists. |
See The saving claim.
Chain state and warnings
| Field | Type | Meaning |
|---|---|---|
readAt | Tip | The chain state every pool in this quote was read at. |
warnings | readonly string[] | Plain language items the interface must show. |
Warnings come from three places: the risk notes on every pool the route touches, the atomicity of the route, and the baseline outcome. They travel with the data rather than only with the screen, so a second consumer of the quote reaches the same conclusions.
Errors
| Class | Thrown when |
|---|---|
QuoteError | The request or the pool set is unusable, for example a non positive input, an unregistered asset, pools read at more than one chain state, or a route that does not allocate the whole input. |
NoRouteError | No route exists for this pair at this size, no pool matches the requested execution classes, or no allocation could be requoted with the venues' own arithmetic. |
NoRouteError extends QuoteError.
The request
interface QuoteRequest {
assetIn: AssetRef;
assetOut: AssetRef;
amountIn: bigint;
slippageBps?: number;
allowNonAtomic?: boolean;
executionClasses?: readonly ExecutionClass[];
}slippageBps falls back to routing.defaultSlippageBps.
allowNonAtomic is off by default, so routes that would settle leg by leg are not enumerated.
executionClasses restricts routing to the given classes. It does not restrict the baseline.