Skip to content

Always quote with limit orders rebased - #4874

Open
fleupold wants to merge 5 commits into
mainfrom
always-quote-with-limit-orders-rebased
Open

Always quote with limit orders rebased#4874
fleupold wants to merge 5 commits into
mainfrom
always-quote-with-limit-orders-rebased

Conversation

@fleupold

@fleupold fleupold commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Description

Remove the "quote with limit orders flag" which becomes the only option to quote now. This is a pre-requisite to removing the Market order class which is a legacy artifact and no longer used. It also allows implementing the haircut logic as a basic fee (since market orders don't allow solvers to determine fees).

The challenge that comes with quoting as limit orders is that drivers cannot accurately compute network fees (as those require a native price in sell token, which is not part of the auction and which aren't usually computed in the driver). The workaround is leaving the fee 0 in this case since it's anyways overridden by the orderbook API with the simulated or reported gas amount * sell token price.

Changes

  • Always quote with limit orders
  • Remove legacy flags
  • Default to zero fee during quotes

How to test

Added a unit test that okx solver can quote with limit orders.

Warning

This PR requires merging infra PRs at the same time that remove the deprecated flags.

@fleupold
fleupold requested a review from a team as a code owner September 5, 2026 09:15
@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Claude finished @fleupold's task in 2m 57s —— View job


PR Review — Always quote with limit orders

  • Gather context (read the diff)
  • Analyze the changes
  • Post inline review comments
  • Post summary

The change is clean and consistent: quotes always build a Limit order with price: None, and both the dex and baseline solvers already fall back to a zero fee when no reference price is present (baseline via the U256::MAX sentinel, dex now via the None branch). Flag removal across driver config and e2e setup is mechanical and I found no dangling references to quote_using_limit_orders. The new okx test correctly exercises the no-reference-price quote path (heuristic gas + fee: "0").

Two things worth confirming (posted as inline comments, non-blocking):

  1. dex/mod.rs:122 — the gas-simulation gate moved from class == Limit to sell_token.is_some(). This also makes market orders in real auctions simulate gas (previously heuristic), and uses price-presence as an implicit "is this a quote" proxy.
  2. solution.rs:243 — the fee fallback now yields a zero fee instead of skipping the solution when the sell token has no reference price. Correct for quotes; the safety for real auctions relies on the autopilot always pricing traded tokens. Consider a comment or a warn! guard so a regression in price population doesn't silently zero out fees.

Nothing here is blocking — both are "confirm the invariant / add a guard" notes.

// Only simulate gas if the auction has a sell token price (ie. we are
// in a proper auction). For quotes, we use the indicated gas
// value from the solver to save time.
let gas = if sell_token.is_some() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The gas-simulation gate changed from order.class == Class::Limit to sell_token.is_some(). Two consequences worth confirming:

  1. Market orders in real auctions now get simulated. Previously a market order (in a priced auction) used heuristic gas; now sell_token.is_some() is true for it, so it goes through simulator.gas(...). That's arguably more accurate, but it's a behavioral change (and a per-order simulation cost) for a path the old code deliberately skipped. Since market orders are being deprecated this is likely fine, but it's worth being explicit that it's intended.

  2. sell_token.is_some() is being used as a proxy for "this is a real auction, not a quote". That coupling is implicit — it works only because quote auctions set price: None for every token (see driver/src/domain/quote.rs:237) and real auctions always price traded tokens. Consider naming the intent more directly (e.g. deriving an is_quote/has_reference_price boolean) so a future change to price population doesn't silently flip this branch.

),
// For quote auctions (which don't contain native prices) we fall back to a zero
// fee. The orderbook API will estimate a proper fee itself.
None => Default::default(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the key semantic change: previously sell_token? made a solver-fee order skip (no solution) when no reference price was available; now it produces a solution with a zero fee.

For the quote path this is exactly what you want. The risk is that it also silently changes behavior for any real auction where a limit order's sell token happens to lack a reference price — instead of skipping, the solver would now settle it with a zero network fee (an unprofitable settlement / effective loss) rather than declining.

In practice this should be safe because the autopilot filters orders whose tokens have no native price, so priced auctions always carry a sell-token reference price. But that invariant is now load-bearing and only enforced elsewhere. Worth either (a) a comment stating the assumption, or (b) a tracing::warn! in the None branch when the auction isn't a quote, so a regression in price population surfaces instead of quietly zeroing fees.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant