# A quote is a statement about the past: what an in-transaction solver fixes, and what it does not

> Canonical: https://blazephoenix.xyz/learn/quotes-are-statements-about-the-past
> License: CC BY 4.0 (attribution + link) · © 2026 BlazePhoenix
> Updated: 2026-08-13



A quote is a promise about a trade that has not happened yet. Every aggregator makes one, and in almost every case the promise is produced by different machinery than the trade: a service computes the route off-chain, and the contract on-chain executes the route it was handed. The contract does not choose; it checks. Whether the route it received was the best one available is not something it can know, and therefore not something a user can verify.

That is a sound engineering arrangement and it is why aggregators are fast and cheap. It has one consequence rarely stated plainly: the strongest claim such a system can make is that its operator is honest. The constraints it enforces on-chain — a minimum output, a deadline — bound how badly the trade can go, but say nothing about whether a better route existed and was not offered.

## Three sources of drift, which are usually collapsed into one

The gap between a quote and a fill is not usually fraud. It is drift, and it has three ordinary and independent sources that a reader should keep apart, because a mechanism that closes one may leave the others untouched.

Temporal drift: the quote is computed at one moment against reserves that move continuously, so by the time the transaction lands, the pool it priced is a different pool. Search drift: the route was chosen by a search over a snapshot, and the search is only as exhaustive as the operator's budget for running it — a fact invisible in the output, since a worse route and a better route are both just numbers. Model drift: any correction applied between the two — a slippage buffer, a fee taken on the way, an approximation used because the exact computation was too expensive — is applied by code the user did not read, to a number the user cannot reproduce.

None of that requires bad intent. All of it is invisible. And the three have different remedies, which is the point of separating them.

```
source of drift    what it is                              what an in-frame solver does
temporal           reserves moved between quote and fill    ELIMINATES (same frame)
search             the search was as good as the budget     ELIMINATES the operator's budget;
                                                            replaces it with the contract's
model              approximation between quote and fill     UNTOUCHED
```

## What the on-chain-solving entry point actually removes

The protocol offers an entry point that takes six scalars — the two tokens, the amount, a minimum, a recipient, a deadline — and works out the route itself, calling the solver in the same frame before any tokens move. The thing that chooses is the thing that trades. Temporal drift between the routing decision and the execution is not reduced; it is structurally absent, because there is no interval. And the route can be re-derived by anyone from the same public state, because it was derived from that state.

Search drift changes character rather than disappearing. The operator's search budget stops mattering and the contract's budget starts mattering instead, and the contract's is smaller. A single-pass allocation over a small fixed set of topologies is not what an unconstrained off-chain search would find. That is the trade stated in the direction that does not flatter us: the distinctive entry point costs the most gas and delivers the least polished routing, and what it buys is a route no operator produced.

It is also worth attributing the protocol's other properties to the right half, because the temptation runs the other way. The output floors, the enforcement against measured balance deltas, the survival of fee-on-transfer tokens and the authentication of venue callbacks all belong to the ordinary settlement side, and a conventional aggregator could adopt every one of them.

## Model drift is the one that survives, and we have a live instance

Execution always asks the venue: the swap is performed by the venue's own code and the result is established by measuring balances. Quoting is where a choice exists. For stable-curve, Solidly-style and cryptoswap venues the quote is obtained by calling the venue's own pricing function. For constant-product, concentrated-liquidity and singleton venues the quote is computed by the protocol from the venue's reserves using the standard formula for that family.

Modelling is how a quote and an execution come to disagree. A model is correct until the venue differs from it in some corner — an unusual fee tier, a hook, a rounding convention — and the disagreement reaches the user as receiving less than they were shown. Asking removes that class of error; computing accepts it in exchange for not having to call the venue twice.

Our live instance is the dynamic-fee family. Those venues are registered with their fee forced to a sentinel value of zero, and that zero flows into the concentrated-liquidity quote, so the quote prices the trade as though the venue charged nothing while execution pays whatever the live fee turns out to be. The realised output is short by exactly that fee. Solving in-frame does not help: both the quote and the execution happen in the same transaction and they still disagree, because the disagreement is in the model rather than in the interval.

## Measure, never declare — the discipline that bounds model drift

What limits the damage is that amounts are established by measuring balances before and after, not by trusting what a function returned or what a caller asserted. The output of a swap is a balance delta on the router, not the number the pool claimed to send. This is also what lets tokens that take a fee on transfer be handled without a separate accounting path: there is no declared amount to be wrong.

The same principle governs the floor. After execution, the router re-derives its floor from the impact it actually measured and the number of legs that actually ran, anchored to a quote taken in the same frame — a value no caller can forge, because no caller supplies it. A floor supplied in calldata can only make that number stricter. That is the difference between a contract that executes a route and one that enforces a policy while executing it.

The qualifications belong in the same paragraph as the guarantee, because a floor is exactly the kind of promise where the exceptions are the content. The reference is the final hop's quote at execution time, not the quote the user was shown — between the two sits everything the market did in the interval. The check runs before the protocol fee is applied, so the floor bounds the pre-fee amount rather than the delivered one. And the guard is inert when that reference is zero. The compact statement — that the floor never falls below 80% of the user's quote — is false in three separate ways, and a reader who took the compact version would be misled about a safety parameter.

## The preview surface: a guarantee restated where nothing can enforce it

There is a read-only surface that returns a preview of a trade: expected output, fee, a floor, a minimum, a gas estimate. Wallets and integrators read it, and every number in it is something someone will act on. We audited it against what the router actually enforces, and the result is the most uncomfortable material in the corpus, because a preview that reads like a guarantee in a protocol whose central claim is the absence of a quote-versus-execution seam is exactly the failure we set out to avoid.

Of everything the preview returns, exactly one number binds: the minimum the caller supplies, and it binds only because the caller passes it again at execution and the router checks it against the recipient's actual balance change. The output, fee and route fields are indicative — honest computations of what the protocol expects, subject to everything that can change between the read and the transaction. The remainder read like guarantees and are not: the floor the preview reports is taken from the caller's own route data rather than derived by the protocol; the field named as the effective minimum omits the protocol floor entirely and is therefore not the bound the router applies; the gas estimate is consumed by nothing anywhere in the system; two route-classification fields are returned as fixed zeros in every case; and a field named as a safety buffer has no counterpart in the router at all.

Two divergences cost money rather than merely confusing. The preview function whose name promises an exact figure falls back to scaling the expected output linearly when it cannot compute the exact one, and returns no flag saying it did — a caller cannot distinguish an exact answer from an approximation. And the preview's output figure is gross, before the protocol fee of 28 bps, while the integration notes tell integrators to derive their minimum from it. An integrator who follows that advice literally sets a minimum the trade cannot meet, or a minimum loose enough to absorb the fee twice.

## What an integrator should do today

These are disclosed rather than fixed, and the register of open findings names each one. The correct practice in the meantime is simple and is right regardless of our defects: derive your minimum from your own price expectation, not from any field in a preview — ours or anyone's — and treat every other number in a preview as an estimate.

The reason that advice is more than caution is the failure mode a hostile or compromised interface has available. The caller supplies the route, the recipient and the minimum, and that minimum is the quantity every other bound falls back to. A hostile interface does not need to break any of our bounds; it only needs to propose a minimum that is non-zero but terrible, which passes every check the contract performs, because the contract cannot know what the user would have chosen. Our refusal to accept a zero minimum — where the reference implementation the industry copies accepts zero and proceeds — is necessary and nowhere near sufficient. What exists against it is an execution proof emitted on every swap, carrying the quote, the realised amount and the floor that was applied, which makes the attack detectable after the fact by anyone including the victim. That is worth having and it is not prevention.

**Verify it yourself:** call the preview off-chain, then execute the same trade and compare the emitted swap event — quote, realised amount and applied floor are all on-chain — against what the preview returned; that comparison is the one test our own suite does not contain

Related: https://blazephoenix.xyz/learn/on-chain-quoting · https://blazephoenix.xyz/learn/wired-is-not-demonstrated · https://blazephoenix.xyz/learn/two-entry-points-calldata-trust
