Skip to main content
A quote round is a single synchronous pass. The borrower’s request comes in, the coordinator does everything it can before and during the solver wait, and the response goes back in the same HTTP exchange. There is no queue, no retry, and no state carried between rounds.

The quote lifecycle

1

Pass the edge screen

Requests are screened before they reach the coordinator. One that arrives without a browser challenge token is answered at the edge with 202 and a challenge page, so only a browser running the Iris app reaches the steps below.
2

Check the origin

The deployed coordinator answers the Iris app’s browser origin only. A request whose Origin header is missing or unrecognised returns 403 before the body is read.
3

Parse the request

The body is parsed against the request schema. Numeric fields arrive as decimal strings and are range-checked before conversion, so malformed input is a clean 400 rather than a server error. A failure here ends the round: no solver is contacted.
4

Validate the request

Three checks run before any fan-out: both collateralToken and debtToken must be protocol-supported tokens, every bit set in venueBitmap must correspond to a registered venue, and every venue the bitmap names must have a market for the pair. Any failure returns 400. The last check is per venue, not “at least one can serve”: a bitmap naming a venue with no market for the pair is rejected even when another named venue could quote it.
5

Select eligible solvers

The coordinator reads its solver registry and filters it down before making a single HTTP call. See Eligibility below.
6

Fan out in parallel

Every eligible solver is called simultaneously with the same intent, each carrying its own fresh quoteId. The round is bounded by the slowest solver, not their sum. A solver that times out costs the round nothing beyond its own timeout.
7

Validate each response

Every returned quote is checked independently: schema, terms, signatures, registry enablement, bond sufficiency, and solver funding. A quote that fails any definitive check is dropped. A dropped quote never fails the round. See Validation.
8

Select the best quote

Among surviving quotes, the lowest fixedRate is ranked best. The response carries that quote inline plus allQuotes, every valid quote from the round; the borrower may take any of them. If no quote survives, the round returns 404.

Eligibility

Not every registered solver sees every request. Four filters run before any HTTP call, so an ineligible solver costs the round no latency at all: These are the reason a healthy, registered solver can see no traffic at all. See the FAQ.

Fan-out and timing

Solvers are called concurrently and independently. The default response window is 5 seconds, raisable per solver during onboarding. A solver that exceeds its window is abandoned for that round: the round does not wait, and the timeout is recorded against that endpoint. Declining is a first-class outcome, not an error. A solver that does not want to quote returns HTTP 404 or a quote with bond: "0"; both are recorded as non-quotes and are treated differently from failures for health purposes. Everything the coordinator can do in advance happens during the solver wait rather than after it. Bond-curve parameters for every enabled bond lock module, and each registered solver’s debt-token balance and allowances, are fetched the moment the request arrives, unawaited and batched, so they have resolved by the time responses need checking against them. Bond and funding validation therefore add no latency to the round.

Validation is convenience-grade

This is the doctrine that explains most of the coordinator’s behaviour. Iris.take() re-verifies every term on-chain. The coordinator’s checks exist to drop quotes that are definitively unsubmittable before a borrower wastes gas on them, not to replicate the contract. That produces two rules:
  • Reject only on a definitive invalid. A signature that recovers to the wrong address is unsubmittable, so the quote is dropped.
  • Fail open when a check cannot run. If bond parameters could not be fetched, bond validation is skipped rather than failing the quote. The contract is the backstop.
The practical consequence for solvers: passing validation here is necessary but not sufficient. A quote that survives the round can still revert at take().

What a quote is

A quote is a signed, short-lived offer. It always carries the Quote signature: an EIP-712 signature over the on-chain Quote struct, which is what take() verifies to bind the solver to these terms. How the bond pull is authorised depends on the solver’s funding mode. take() tries a standing ERC-20 approval to Iris first; a solver maintaining one signs nothing further and omits the Permit2 pair. Otherwise the quote also carries the Permit2 signature: an EIP-712 signature over a Permit2 PermitSingle authorising Iris to pull exactly this quote’s bond in the debt token, travelling with the quote because the solver is not in the call path to approve the pull at settlement. Quotes expire within two minutes of issue. They are not stored, not re-offered, and not cancellable: expiry is the only exit.

What the coordinator is not

  • Not an order book. Intents are seen only by that round’s eligible solvers and are never persisted; a round is private to its participants.
  • Not a matching engine. It returns a quote; it never settles one. Settlement is the borrower calling take().
  • Not custodial. It never holds tokens, keys, or positions.
  • Not open enrolment. Solvers are onboarded through a whitelist.