Upgrade to 2.368.2#15
Open
jmg-duarte wants to merge 368 commits into
Open
Conversation
# Description Further untangles the `shared` crate. # Changes * deletes `bytes.rs` which was forgotten in an old PR * moved `trade_finding` into `price-estimation` * move `tenderly_api` arguments from `shared::Arguments` to `price_estimation::Arguments` * removed a few dependencies * downgraded a few dependencies to `dev-dependencies` new crates split off of `shared`: * `gas-price-estimation` * `price-estimation` * `bad-tokens` Unfortunately `price-estimation` is relying on a few utils which didn't make much sense to move into a new crate so I duplicated a few things in `price_estimation::utils` but I think this does not outweigh the structure and compile time gained by this PR. This PR does again not migrate the catch all `alloy` imports to the more specific sub-crates (e.g. `alloy_primitives`) ## How to test compiler
…cowprotocol#4216) # Description Move native price cache, concurrent requests, approximation tokens, and balancer SOR URL settings from CLI arguments into the TOML config file. Introduce a shared NativePriceConfig in the shared crate that both autopilot and orderbook embed via serde flatten. Also migrate orderbook's native price estimator selection and results_required from CLI to config. # Changes * Moves shared native price settings (cache max-age, concurrent requests, approximation tokens) into a new `shared::price_estimation::config::native_price` module, used by both autopilot and orderbook via `#[serde(flatten)]` * Moves orderbook-specific settings (native price estimators, fallback estimators, results-required) from CLI args to the orderbook TOML config * Removes `--balancer-sor-url` (unused) * Adds unit tests for (de)serialization of the new config structs ## Migrated settings ### Shared (autopilot + orderbook) These settings were in `shared::price_estimation::Arguments` (CLI) and now live in the `[native-price-estimation]` section of each service's TOML config, flattened from the shared `NativePriceConfig`. | Old CLI Argument | TOML Key | |---|---| | `--native-price-cache-max-age` | `native-price-estimation.cache.max-age` | | `--native-price-cache-concurrent-requests` | `native-price-estimation.cache.concurrent-requests` | | `--native-price-approximation-tokens` | `native-price-estimation.approximation-tokens` | | `--balancer-sor-url` | **removed** | ### Orderbook-only These settings were in `orderbook::arguments::Arguments` (CLI) and now live in the `[native-price-estimation]` section of the orderbook TOML config. | Old CLI Argument | TOML Key | |---|---| | `--native-price-estimators` | `native-price-estimation.estimators` | | `--native-price-estimators-fallback` | `native-price-estimation.fallback-estimators` | | `--fast-price-estimation-results-required` | `native-price-estimation.results-required` | ## Example ### Orderbook Before: ```bash orderbook \ --native-price-cache-max-age=5m \ --native-price-cache-concurrent-requests=4 \ --native-price-approximation-tokens="0xaaa...111|0xbbb...222,0xccc...333|0xddd...444" \ --native-price-estimators="[[{type = \"CoinGecko\"}, {type = \"OneInchSpotPriceApi\"}]]" \ --native-price-estimators-fallback="[[{type = \"CoinGecko\"}]]" \ --fast-price-estimation-results-required=3 \ --config=/path/to/orderbook.toml \ --bind-address=0.0.0.0:8080 ``` After — add to `orderbook.toml`: ```toml [native-price-estimation] estimators = [[{ type = "CoinGecko" }, { type = "OneInchSpotPriceApi" }]] fallback-estimators = [[{ type = "CoinGecko" }]] results-required = 3 approximation-tokens = [ ["0xaaa...111", "0xbbb...222"], ["0xccc...333", "0xddd...444"], ] [native-price-estimation.cache] max-age = "5m" concurrent-requests = 4 ``` ### Autopilot Before: ```bash autopilot \ --native-price-cache-max-age=10m \ --native-price-cache-concurrent-requests=2 \ --native-price-approximation-tokens="0xaaa...111|0xbbb...222" \ --config=/path/to/autopilot.toml ``` After — add to `autopilot.toml` (inside the existing `[native-price-estimation]` section): ```toml [native-price-estimation] # ... existing autopilot-specific settings (estimators, etc.) ... approximation-tokens = [ ["0xaaa...111", "0xbbb...222"], ] [native-price-estimation.cache] max-age = "10m" concurrent-requests = 2 ``` ## How to test Staging --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
# Description During the Axum migration we (unknowingly) stopped supporting unprefixed hex values — this was due to Axum using the JSON deserialization (which for OrderUids for example, was rejecting non-prefixed hex) while warp used FromStr which had a more lenient implementation. This PR unifies the FromStr and serde impls and adds tests to the endpoints to ensure # Changes We notified downstream partners but this single path was forgotten in the respective migration * Refactor cancel_order handler to use Axum typed extractors (Path<OrderUid>, Json<CancellationPayload>) instead of manual parsing * Change solver_competition_v2 auction_id to u64 so negative values return BAD_REQUEST * Update OrderUid deserialization and FromStr to delegate 0x handling to const_hex (which strips the prefix internally) * Add extraction tests across all orderbook API endpoints verifying hex params (OrderUid, Address, B256, AppDataHash) accept both prefixed and non-prefixed input ## How to test Run tests Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
# Description It's really annoying not to have a standard TOML formatting utility, without it we'll bikeshed on something generally not worth losing time over. This PR addresses that issue by introducing [Tombi](https://github.com/tombi-toml/tombi) in several forms: * CLI * VSCode (extension recommendation to ensure the right extension + extension config) * Zed Note: Tombi also does linting and is aware of the deprecation of package.authors in Cargo.toml, however, the book doesn't mention much of an alternative because in reality it's not just the package submitter etc, see rust-lang/cargo#16458 for more info. # Changes * New recipe for the Justfile * Editor configs * Add tombi to CI too * Formatted all *.toml ## How to test * Test it in your respective editor * Run `just tombi-fmt` (add `--check` for check)
# Description While fixing my config I got Claude to address my own comments on cowprotocol#4223 Move `signature_validator` and `zeroex_api` modules into their own workspace crates and update all dependents to import from the new crates. This continues the effort to reduce the `shared` crate's surface area. # Changes * Extract zeroex-api from shared — this one was a freebie and doesn't make a lot of sense being in shared as it so specific * Extract signature-validator — this one allows us to compile cow-amm without shared (see image below) * Remove thiserror in crates that had errors with a single variant or similar, in favor of manual implementation Left is after, right is before <img width="1760" height="891" alt="Screenshot 2026-03-03 at 14 10 09" src="https://github.com/user-attachments/assets/27aef0e7-d5d8-4d1c-a9d2-a912ea43bc91" /> ## How to test Compiler + tests --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: MartinquaXD <martin.beckmann@protonmail.com>
# Description We got a report about failing simulations on Polygon. It turns out that when we put in this change we had 1 ETH in mind which is fine on ETH chains, but it also translates to 1 POL which is worth about $0.9 and leads to simulation failures due to insufficient gas.
…col#4230) # Description While depending on `alloy` is convenient because it bundles everything inside 1 dependency it also hides what parts are actually needed and can delay the compilation of crates unnecessarily. # Changes replace `alloy` dependency with the actually used sub-crates like `alloy-primitives` and `alloy-provider` this PR mostly focuses on the smaller "leaf" dependency crates as they are manageable in size and allowing them to compile earlier is more important than optimizing crates like `driver`, and `autopilot`. So far this PR only improves the compile time very slightly by making sure `contracts` does not indirectly depend on `aws-sdk-kms` as that is insanely slow to compile. The effects of this change will be more pronounced when we change the `contracts` crate to be compiled as individual `crates`. But I think even without huge compile time gains being explicit about our dependencies still makes sense. ## How to test compiler
# Description This PR moves the DB CLI arguments to a configuration file. Additionally, this PR introduces the configs/ crate to ease mix and matching parts of the config and to have one more "compilation caching" place, to reduce the size of the shared crate. # Changes * Create configs/ crate * Migrate & unify the db arguments from shared, orderbook and autopilot in configs/database # Migration Guide Database connection settings move from CLI args to the TOML config file (`[database]` section) for both autopilot and orderbook. ## CLI args -> TOML | CLI arg / env var | TOML replacement (`[database]`) | |---|---| | `--db-write-url` / `DB_WRITE_URL` | `write-url` | | `--db-read-url` / `DB_READ_URL` (orderbook) | `read-url` | | `--db-max-connections` / `DB_MAX_CONNECTIONS` | `max-connections` | | `--insert-batch-size` / `INSERT_BATCH_SIZE` (autopilot) | `insert-batch-size` | Keeping removed args in your startup command will cause an error. ## TOML example ```toml [database] write-url = "postgresql://user:password@host:5432/dbname" read-url = "postgresql://readonly:password@replica:5432/dbname" # orderbook only, optional max-connections = 10 insert-batch-size = 500 # autopilot only ``` All fields have defaults matching the old CLI defaults (`write-url = "postgresql://"`, `max-connections = 10`, `insert-batch-size = 500`, `read-url` falls back to `write-url`). Omitting `[database]` entirely preserves previous behavior. ## How to test E2E tests + staging --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
# Description When replacing the `alloy` dependency with its sub-depdencies I let compilation errors guide me which features need to be enabled. However, this was not enough since `https` support needs to be enabled via a feature and if that's missing we'll only encounter runtime errors but not compile time errors. `reqwest` will throw errors like `invalid URL, scheme is not http`. # Changes Enabled `https` on the workspace level to avoid feature unification causing us to miss `https` support in future edge cases Added a unit test to ensure that `https` requests succeed. ## How to test new unit test
# Description Log format has changed so I updated instructions how to use it for Claude.
# Description Follow up to cowprotocol#4238. While that PR correctly identified the issue that `https` was not enabled when is should have been it did not resolve it correctly. It incorrectly added the tls feature on the workspace toml assuming this will cause the feature to always be enabled but that's actually not correct. The driver still did not support https. I was able to reproduce that by copying the new `test_https` unit test to the driver main and running it from there. `cargo test -- test_https` passed while `cargo test -p driver -- test_https` did not. This indicates that `https` support was only enabled when the whole workspace gets compiled as one. When we only compiled the `driver` feature unification was not there to pull in the necessary features. This PR addresses this by explicitly enabling all the necessary features such that every crate can be compiled and tested individually without complaints. # Changes Add a bunch of features that were previously assumed to not be needed because feature unification pulled them in without our knowledge. Since `alloy` likes to follow the pattern of using feature flags to enable compilation of sub-crates I avoided the use of feature flags by depending on the underlying sub-crate whenever possible. For example this caused me to introduce `alloy_rpc_types_eth` and `alloy_rpc_types_trace` on the workspace level. This PR only fixes the symptom but doesn't prevent us from relying on feature unification without our knowledge again. This should be addressed in a follow up PR. ## How to test After that was done I repeated the test with `cargo -p driver -- test_https` and it passed. Indicating that the `ethrpc` crate now correctly causes https to be supported in any crate that depends on it.
…owprotocol#4235) # Description Move ethflow, cow_amm, and run_loop configurations from CLI arguments to dedicated TOML config file modules. Add TestDefault impls for ethflow and run_loop configs so E2E tests use appropriate values (skip_event_sync, shorter timeouts) without manual overrides in test setup code. # Changes * Move ethflow to the config * Move cow_amm to the config * Move run_loop to the config * Move other loose arguments to the config ## How to test Tested in staging # Migration Guide The following autopilot CLI arguments have moved to the TOML config file. ## Ethflow (`[ethflow]`) | CLI arg / env var | TOML key (`[ethflow]`) | |---|---| | `--ethflow-contracts` / `ETHFLOW_CONTRACTS` | `contracts` | | `--ethflow-indexing-start` / `ETHFLOW_INDEXING_START` | `indexing-start` | | `--skip-event-sync` / `SKIP_EVENT_SYNC` | `skip-event-sync` | ## CoW AMM (`[cow-amm]`) | CLI arg / env var | TOML key (`[cow-amm]`) | |---|---| | `--cow-amm-configs` / `COW_AMM_CONFIGS` | `[[cow-amm.contracts]]` (see below) | | `--archive-node-url` / `ARCHIVE_NODE_URL` | `archive-node-url` | The `--cow-amm-configs` pipe-separated format (`<factory>\|<helper>\|<block>`) is replaced by TOML tables: ```toml [cow-amm] archive-node-url = "https://archive.example.com" [[cow-amm.contracts]] factory = "0x..." helper = "0x..." index-start = 12345678 ``` ## Run loop (`[run-loop]`) | CLI arg / env var | TOML key (`[run-loop]`) | |---|---| | `--max-run-loop-delay` / `MAX_RUN_LOOP_DELAY` | `max-delay` | | `--max-winners-per-auction` / `MAX_WINNERS_PER_AUCTION` | `max-winners-per-auction` | | `--max-solutions-per-solver` / `MAX_SOLUTIONS_PER_SOLVER` | `max-solutions-per-solver` | | `--enable-leader-lock` / `ENABLE_LEADER_LOCK` | `enable-leader-lock` | | `--compress-solve-request` / `COMPRESS_SOLVE_REQUEST` | `compress-solve-request` | | `--submission-deadline` / `SUBMISSION_DEADLINE` | `submission-deadline` | | `--max-settlement-transaction-wait` / `MAX_SETTLEMENT_TRANSACTION_WAIT` | `max-settlement-transaction-wait` | | `--solve-deadline` / `SOLVE_DEADLINE` | `solve-deadline` | ## Standalone fields | CLI arg / env var | TOML key | |---|---| | `--metrics-address` / `METRICS_ADDRESS` | `metrics-address` | | `--api-address` / `API_ADDRESS` | `api-address` | | `--shadow` / `SHADOW` | `shadow` | | `--disable-order-balance-filter` / `DISABLE_ORDER_BALANCE_FILTER` | `disable-order-balance-filter` | | `--max-maintenance-timeout` / `MAX_MAINTENANCE_TIMEOUT` | `max-maintenance-timeout` | | `--run-loop-native-price-timeout` / `RUN_LOOP_NATIVE_PRICE_TIMEOUT` | `native-price-timeout` | | `--unsupported-tokens` / `UNSUPPORTED_TOKENS` | `unsupported-tokens` | | `--min-order-validity-period` / `MIN_ORDER_VALIDITY_PERIOD` | `min-order-validity-period` | | `--max-auction-age` / `MAX_AUCTION_AGE` | `max-auction-age` | All defaults remain unchanged.
# Description When I was working on another feature (the debug endpoint) I noticed that there is a race condition where we sometimes insert "invalid" order event to the DB. From logs ``` 09:19:13.717 stored order events label=Executing count=1 09:19:13.733 filtered orders reason=insufficient_balance count=1 orders=[0x060a...] 09:19:13.737 stored order events label=Invalid count=1 09:19:13.756 stored order events label=Traded count=1 ``` Order is in `executing` state, then settles onchain. If the indexing runs now and we set the order to `traded` all is well. However if the in cache update runs first it's possible the wallet no longer has the necessary balance as it was traded away in the just executed swap and we consider it invalid and we insert the invalid event for an order that went through perfectly well. # Changes * [x] Don't consider in-flight orders invalid * [x] Move in-flight filtering logic from run loop to solvable_orders (move upstream) ## How to test I had an e2e test to reproduce this which failed 6/10 times. After the fix it fails 0/10. --------- Co-authored-by: Martin Magnus <martin.beckmann@protonmail.com>
# Description Cargo audit started flagging version 0.11.13, this PR upgrades it to solve the audit issue # Changes * Upgrade quinn-proto to 0.11.14 ## How to test cargo-audit
# Description Updates the failing trivy action # Changes * Bump trivy to 0.35 ## How to test CI
# Description Migrates the OKX solver from the https://github.com/gnosis/solvers repo as per cowprotocol#4234. ## How to test Migrated tests. ## How to migrate 1 line config change in the infra, which basically replaces the image.
# Description
Add a debug endpoint for order investigation. Given an order UID, it
returns the full lifecycle: order data, events
(created/ready/executing/traded), auction participation, proposed
solutions, executions, trades, settlement attempts, and fee policies.
Protected by a configurable auth token header.
# Changes
* New `GET /api/v1/debug/order/{uid}` endpoint behind `x-auth-token`
header auth
* `DebugReport` DB layer aggregates data from various tables (see data
sources)
* New `auction_orders` junction table (V106) to efficiently look up all
auctions an order participated in, replacing indirect derivation through
proposed_solutions/executions
* `save_auction()` now populates the junction table alongside
`competition_auctions`
* Configurable auth tokens via `debug_route_auth_tokens` in orderbook
config
* E2E test covering the full happy path + auth failure cases
## Queried tables
* orders (via single_order)
* order_events (via get_all)
* proposed_trade_executions + proposed_solutions (via
find_solutions_for_order — that's a JOIN)
* order_execution (via read_by_order_uid)
* trades (via trades)
* auction_orders (via fetch_auction_ids_by_order_uid)
* competition_auctions (via fetch_multiple)
* settlement_executions (via read_by_auction_ids)
* fee_policies (via fetch_by_order_uid)
## How to test
`cargo nextest run -p e2e debug_order --test-threads 1 --run-ignored
ignored-only`
Test will be flaky until we get
cowprotocol#4239 in.
# Follow up
Include a concrete reason why an order was filtered out of an auction if
it was filtered out.
# Description Currently it's quite annoying to figure out when a solver provided a solution for a given order that fails to encode. # Changes This PR adjusts the log to also mention the order uids of the solution that failed to encode.
# Description While testing a feature, I noticed that the driver's submission account is currently rendered in our infra as follows: ```toml [[drivers]] name = "okx-solve" url = "http://mainnet-driver-staging-.../" [drivers.submission-account] kms = "arn:aws:kms:eu-central-...." ``` , where the submission-account is separated, which is not really convenient when manually editing configs. This PR flattens the submission account config, so it will be rendered as: ```toml [[drivers]] name = "okx-solve" url = "http://mainnet-driver-staging-.../" kms = "arn:aws:kms:eu-central-...." ```
# Description Addresses cowprotocol#4235 (comment) # Changes * Moves autopilot configs to configs crate * Moves fee factor to configs crate ## How to test Compilation + tests
This effectively replicates gnosis/solvers#203 # Summary - Add a new solver that integrates with the https://web3.bitget.com/en/docs/swap/ API to find swap routes, following existing patterns - ~~The Bitget API uses a two-step POST flow: `quote` (to get the optimal routing market and output amount) followed by `swap` (to get the on-chain calldata)~~ The BitGet team suggested using the `request_mod="rich"` param in the `/swap` API, which makes the response contain much more data, including the `outAmount`. - ~~To mitigate the race condition between `quote` and `swap` calls, slippage is applied to the quoted output and passed as `toMinAmount` to the swap endpoint, ensuring consistency between what the calldata enforces on-chain and what the solver reports~~ Not needed anymore because of the previous point - Only sell orders are supported - the Bitget API has no `exactOut` mode # Changes - Bitget API client and DTOs with HMAC-SHA256 request signing, base64 calldata decoding, typed ChainName enum, and serialize::U256 for amount fields - TOML config loading (endpoint, chain-id, api-key, api-secret) - E2E tests: market sell order, buy order rejection, insufficient liquidity, and out-of-price limit order - `config/example.bitget.toml` - Example configuration # How to test New unit and manual e2e tests (ignored by default).
# Description Essentially the same as cowprotocol#4246 but for the orderbook # Changes * Move orderbook configs to the configs crate * Extract SameTokensPolicy ## How to test Compilation + tests
…rate (cowprotocol#4253) # Description Extract shared configuration types (`OrderQuoting`, `BannedUsersConfig`, `HttpClient`) from CLI arguments into the `configs` crate as TOML-deserialized structs. This continues the migration of runtime configuration from clap CLI args to structured TOML config files. # Changes * Move `OrderQuotingArguments` and `ExternalSolver` from `shared::arguments` (clap) to `configs::order_quoting` (serde/TOML), renaming to `OrderQuoting` * Deduplicate `BannedUsersConfig` — was duplicated in `configs::autopilot::banned_users` and `configs::orderbook::banned_users`, now a single `configs::banned_users` module shared by both * Move `HttpClient` config to `configs::http_client` * Add `TestDefault` impl for `OrderQuoting` and test helpers (`ExternalSolver::new`, `OrderQuoting::test_with_drivers`) * Update all e2e tests to pass `price-estimation-drivers` via config structs instead of the removed CLI arg * Add deserialization and roundtrip tests for `OrderQuoting` ## How to test Existing tests # Migration Guide The following CLI arguments have moved to TOML config files. This applies to **both autopilot and orderbook** services. ## Order Quoting (`[order-quoting]`) | CLI arg / env var | TOML key (`[order-quoting]`) | |---|---| | `--price-estimation-drivers` / `PRICE_ESTIMATION_DRIVERS` | `[[price-estimation-drivers]]` (see below) | | `--eip1271-onchain-quote-validity` / `EIP1271_ONCHAIN_QUOTE_VALIDITY` | `eip1271-onchain-quote-validity` | | `--presign-onchain-quote-validity` / `PRESIGN_ONCHAIN_QUOTE_VALIDITY` | `presign-onchain-quote-validity` | | `--standard-offchain-quote-validity` / `STANDARD_OFFCHAIN_QUOTE_VALIDITY` | `standard-offchain-quote-validity` | The `--price-estimation-drivers` pipe/comma-separated format (`name|url,name2|url2`) is replaced by TOML tables: ```toml [order-quoting] eip1271-onchain-quote-validity = "10m" presign-onchain-quote-validity = "10m" standard-offchain-quote-validity = "1m" [[order-quoting.price-estimation-drivers]] name = "solver1" url = "http://solver1:8080" [[order-quoting.price-estimation-drivers]] name = "solver2" url = "http://solver2:8080" ``` ## Banned Users `BannedUsersConfig` is now shared between autopilot and orderbook (previously duplicated). No config format changes — the `[banned-users]` TOML section remains the same. ## HTTP Client (`[http-client]`) | CLI arg / env var | TOML key (`[http-client]`) | |---|---| | `--http-timeout` / `HTTP_TIMEOUT` | `http-timeout` | All defaults remain unchanged.
# Description - Use the canonical Bitget API path (/bgw-pro/swapx/pro/) for HMAC signature computation instead of deriving it from the configured endpoint URL - When a proxy is configured, the request URL path differs from what Bitget expects in the signature, causing authentication failures - The HTTP request still goes to the configured (possibly proxied) URL - only the signature computation changes - I think it was in one of the original PR comments, but I forgot about it somehow ## How to test Existing tests. Staging.
# Description When orders get filtered from an auction or marked invalid, we now record why it happened. This PR adds a reason column to the order_events table so we can distinguish between e.g. insufficient_balance, banned_user, missing_price etc. Currently these reasons are only visible in the DB / metrics. # Changes <!-- List of detailed changes (how the change is accomplished) --> [x] New migration (V107): adds OrderFilterReason enum type and reason column to order_events [x] `solvable_orders` tracks the specific OrderFilterReason alongside each filtered/invalid order UID [x] Added a new filter reason when we filter an order out because it's already in-flight (= being submitted) [x] Added to order debug endopint ## How to test ``` cargo nextest run -p e2e local_node_debug_order --test-threads 1 --run-ignored ignored-only ```
# Description Simulator refactor requires to move out a couple of dependencies out of shared and reuse them elsewhere. One of them is price_estimation (cowprotocol#4258 with http-client refactor). As both the price_estimation and http-client have their respective configs - having `price_estimation` depend on `http-client` would cause cyclic dependencies on `configs`. # Changes This removes the dependency of configs on price_estimation making it possible to refactor further common types. It also does make sense for other crates to depend on configs, instead of configs depending on other crates. ## How to test E2E tests, no code changes, just moving code around.
Some BitGet chain names were inconsistent and don't align with [the official docs](https://web3.bitget.com/en/docs/swap/). This PR fixes it. Tested on staging on each chain.
# Changes - Remove unused bytes.rs module and empty url.rs from `crates/solvers/src/util/` - Remove `fmt/hex.rs` module, replacing `Hex<'a>` wrapper with inline `const_hex::encode_prefixed` calls (already a dependency) - Replace `Bytes<Vec<u8>>` in `eth::Tx` with `alloy::primitives::Bytes` which provides hex debug formatting out of the box - Use `const_hex::decode` in Bitget DTO instead of manually stripping 0x prefix + `hex::decode` - Drop the `hex` crate dependency from solvers (no longer needed after switching to `const_hex`) ## How to test Existing tests
# Description During the simulator crate refactor I had to move a couple of types out of shared to avoid cyclic dependency. It also makes sense since price_estimation essentially duplicated http-client logic. # Changes Creates a new crate `http-client` where the previously `shared::http_client` is present. Updated imports. De-duplicated `price-estimation` http client,. ## How to test E2E tests should pass. Logic is the same. --------- Co-authored-by: Martin Magnus <martin.beckmann@protonmail.com>
# Description Some insanely complicated quotes exceed the hardcoded 12M gas limit on the simulation. I'm not sure why originally picked the very big but not the highest possible value of 8M which we later bumped to 12M. # Changes This PR now makes this value configurable and sets the default to ethereum's maximum amount of gas a single tx may consume. Any quote that needs more gas than this can definitely not be included in an ethereum block.
…der sooner again for auction (cowprotocol#4528) ## Release in-flight orders once their settlement attempt fails `fetch_in_flight_orders` kept an order in-flight until the auction deadline block passed, even after the winning solver had already aborted its submission (e.g. driver returns `FailedToSubmit`). This delayed the order's re-entry into auctions by up to the full settle deadline. Now the query also releases an order as soon as its winning solution has a recorded `settlement_executions` outcome that isn't `success`, using data we already store. Extended the `postgres_fetch_inflight_orders` test to cover the failed-attempt case (fails without the fix, passes with it). see [slack conversation](https://nomevlabs.slack.com/archives/C0361CDD1FZ/p1781689280454159?thread_ts=1781685304.590139&cid=C0361CDD1FZ) --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
# Description The Hermod team raised that we were querying the zero/burn address quite a bit, since it doesn't make any sense for us to check if that specific address is banned, we start bypassing it — less network requests after all. # Changes * Do not lookup if the zero/burn address is banned
# Description The current logic of pre-allocating memory for the `/solve` request has a few downsides: 1. does not consider that requests can contain a significant amount of `liquidity` data 2. has no way of dynamically correcting the allocation size as we go. For example if our estimates how much memory orders and liquidity require is wrong it needs to be tweaked in the code (or a config parameter). # Changes The new logic groups requests into 4 kinds which all have unique sizes on average and therefor memory requirements: * quote without liquidity * quote with liquidity * auction without liquidity * auction with liquidity For each type we keep track of the biggest request we've seen so far. So when we have to allocate memory for a new request we first check what kind of requests it is and then allocate the memory for the biggest requests we've seen so far. We also overallocate a tiny amount since allocating not enough memory is quite expensive since the allocation will double in size. After we know the size of the final allocation we update the counter accordingly. Since the sizes of requests within each group don't vary significantly we are not overallocating much memory on averaged. Also keep in mind that overallocating by 100% is still better than slightly underallocating memory since vectors have a growth factor of 2. ## How to test tested in the shadow competition memory profiles went from indicating that extra memory had to be allocated for serializing orders and liquidity sources to not requiring any additional memory (while still being only slightly larger than the final bytes needed). <img width="1024" height="834" alt="Screenshot 2026-06-17 at 11 34 14" src="https://github.com/user-attachments/assets/faa285c9-5e57-47a7-8c15-ea308b05c0ba" /> <img width="824" height="450" alt="Screenshot 2026-06-17 at 11 34 34" src="https://github.com/user-attachments/assets/f7eca423-389c-4c92-a486-0626c7ccc0f7" /> Also while it's still too early to tell for sure it looks like the more accurate allocations lead to more reasonable memory usage overall. Not sure if that insane linear growth is due to the allocator getting confused or what (I combed through the code and I couldn't find a memory leak and only the shadow arbitrum pod looks like this) <img width="1902" height="385" alt="Screenshot 2026-06-17 at 11 36 41" src="https://github.com/user-attachments/assets/24aa6cb8-c4c2-42b2-a783-fbb2c40808de" /> The worst we over-allocated in a few hours was 2.5% so I think this is pretty good for such a simple solution. <img width="1857" height="811" alt="Screenshot 2026-06-17 at 11 50 37" src="https://github.com/user-attachments/assets/037b52cd-5f40-4bd5-a9de-214d838f727a" />
# Description Currently our balance override logic does not support native eth (`0xeee...eeee`) because it's not an ERC20 token. # Changes Added a new override enum only used for native eth. Also added a fast path to return early before sending any network requests. ## How to test Added an (ignored) test
# Skip volume fee on wrapped↔native (WETH→ETH) same-token trades
Same-token trades (`sell_token == buy_token`) already skip the volume
fee unless `enable_sell_equals_buy_volume_fee` (off by default) is set.
This extends "same-token" to native ETH buys: `WETH → ETH` (`buy_token
== BUY_ETH_ADDRESS`) and the fee is dropped on both the quote and the
settlement.
## Changes
- `shared/fee.rs`: `get_applicable_volume_fee_factor` takes
`native_token` and skips the fee for the native same-token case.
- `model/order.rs`: extracted `is_same_buy_and_sell_token(sell, buy,
native)`, reused by both the fee policy and order validation.
- `orderbook` (`QuoteHandler`) and `autopilot` (`ProtocolFees`) thread
`native_token` through so quote and settlement agree.
## Tests
- Unit: `shared::fee::tests::test_same_token_volume_fee_skipped`
- E2E: `local_node_volume_fee_{dropped_on_same_token,
charged_on_same_token_when_enabled, dropped_on_wrapped_to_native_token}`
# Description Incorporating feedback from @jmg-duarte from slack # Changes * Make claude inline comments * Use latest available model * Add a minimalistic review skill with the feedback received so far ## How to test https://github.com/cowprotocol/claude-gate-repro/pull/4 --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cowprotocol#4546) This PR contains the following updates: | Package | Type | Update | Change | Pending | |---|---|---|---|---| | [taiki-e/install-action](https://redirect.github.com/taiki-e/install-action) | action | patch | `v2.81.1` → `v2.81.8` | `v2.82.2` (+5) | --- ### Release Notes <details> <summary>taiki-e/install-action (taiki-e/install-action)</summary> ### [`v2.81.8`](https://redirect.github.com/taiki-e/install-action/releases/tag/v2.81.8): 2.81.8 [Compare Source](https://redirect.github.com/taiki-e/install-action/compare/v2.81.7...v2.81.8) - Update `vacuum@latest` to 0.29.2. - Update `parse-dockerfile@latest` to 0.1.7. - Update `mise@latest` to 2026.6.1. - Update `cargo-shear@latest` to 1.13.1. ### [`v2.81.7`](https://redirect.github.com/taiki-e/install-action/releases/tag/v2.81.7): 2.81.7 [Compare Source](https://redirect.github.com/taiki-e/install-action/compare/v2.81.6...v2.81.7) - Update `wasmtime@latest` to 45.0.1. - Update `vacuum@latest` to 0.29.1. - Update `syft@latest` to 1.45.1. - Update `rclone@latest` to 1.74.3. - Update `cargo-audit@latest` to 0.22.2. ### [`v2.81.6`](https://redirect.github.com/taiki-e/install-action/releases/tag/v2.81.6): 2.81.6 [Compare Source](https://redirect.github.com/taiki-e/install-action/compare/v2.81.5...v2.81.6) - Update `prek@latest` to 0.4.4. - Update `cargo-shear@latest` to 1.13.0. ### [`v2.81.5`](https://redirect.github.com/taiki-e/install-action/releases/tag/v2.81.5): 2.81.5 [Compare Source](https://redirect.github.com/taiki-e/install-action/compare/v2.81.4...v2.81.5) - Update `vacuum@latest` to 0.29.0. - Update `uv@latest` to 0.11.19. - Update `typos@latest` to 1.47.2. - Update `mise@latest` to 2026.6.0. ### [`v2.81.4`](https://redirect.github.com/taiki-e/install-action/releases/tag/v2.81.4): 2.81.4 [Compare Source](https://redirect.github.com/taiki-e/install-action/compare/v2.81.3...v2.81.4) - Update `vacuum@latest` to 0.28.4. - Update `typos@latest` to 1.47.1. - Update `syft@latest` to 1.45.0. - Update `cargo-neat@latest` to 0.4.0. - Update `cargo-mutants@latest` to 27.1.0. ### [`v2.81.3`](https://redirect.github.com/taiki-e/install-action/releases/tag/v2.81.3): 2.81.3 [Compare Source](https://redirect.github.com/taiki-e/install-action/compare/v2.81.2...v2.81.3) - Update `vacuum@latest` to 0.28.3. - Update `uv@latest` to 0.11.18. - Update `trivy@latest` to 0.71.0. ### [`v2.81.2`](https://redirect.github.com/taiki-e/install-action/releases/tag/v2.81.2): 2.81.2 [Compare Source](https://redirect.github.com/taiki-e/install-action/compare/v2.81.1...v2.81.2) - Update `mise@latest` to 2026.5.18. - Update `cargo-semver-checks@latest` to 0.48.0. </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - "on monday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cowprotocol/services). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMzEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjIzMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…owprotocol#4545) This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [github/codeql-action](https://redirect.github.com/github/codeql-action) | action | patch | `v4.36.0` → `v4.36.2` | --- ### Release Notes <details> <summary>github/codeql-action (github/codeql-action)</summary> ### [`v4.36.2`](https://redirect.github.com/github/codeql-action/releases/tag/v4.36.2) [Compare Source](https://redirect.github.com/github/codeql-action/compare/v4.36.1...v4.36.2) - Cache CodeQL CLI version information across Actions steps. [#​3943](https://redirect.github.com/github/codeql-action/pull/3943) - Reduce requests while waiting for analysis processing by using exponential backoff when polling SARIF processing status. [#​3937](https://redirect.github.com/github/codeql-action/pull/3937) - Update default CodeQL bundle version to [2.25.6](https://redirect.github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.6). [#​3948](https://redirect.github.com/github/codeql-action/pull/3948) ### [`v4.36.1`](https://redirect.github.com/github/codeql-action/releases/tag/v4.36.1) [Compare Source](https://redirect.github.com/github/codeql-action/compare/v4.36.0...v4.36.1) No user facing changes. </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - "on monday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cowprotocol/services). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMzEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjIzMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…l#4544) This PR contains the following updates: | Package | Type | Update | Change | Pending | |---|---|---|---|---| | [actions/checkout](https://redirect.github.com/actions/checkout) | action | patch | `v6.0.2` → `v6.0.3` | `v7.0.0` (+1) | --- ### Release Notes <details> <summary>actions/checkout (actions/checkout)</summary> ### [`v6.0.3`](https://redirect.github.com/actions/checkout/blob/HEAD/CHANGELOG.md#v603) [Compare Source](https://redirect.github.com/actions/checkout/compare/v6.0.2...v6.0.3) - Fix checkout init for SHA-256 repositories by [@​yaananth](https://redirect.github.com/yaananth) in [#​2439](https://redirect.github.com/actions/checkout/pull/2439) - fix: expand merge commit SHA regex and add SHA-256 test cases by [@​yaananth](https://redirect.github.com/yaananth) in [#​2414](https://redirect.github.com/actions/checkout/pull/2414) </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - "on monday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cowprotocol/services). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMzEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjIzMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…tion to 2fee155 (cowprotocol#4543) This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [anthropics/claude-code-action](https://redirect.github.com/anthropics/claude-code-action) | action | digest | `4d7e1f0` → `2fee155` | --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - "on monday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cowprotocol/services). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMzEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjIzMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…cowprotocol#4548) This PR contains the following updates: | Package | Type | Update | Change | Pending | |---|---|---|---|---| | [tombi-toml/setup-tombi](https://redirect.github.com/tombi-toml/setup-tombi) | action | patch | `v1.1.1` → `v1.1.2` | `v1.1.4` (+1) | --- ### Release Notes <details> <summary>tombi-toml/setup-tombi (tombi-toml/setup-tombi)</summary> ### [`v1.1.2`](https://redirect.github.com/tombi-toml/setup-tombi/releases/tag/v1.1.2) [Compare Source](https://redirect.github.com/tombi-toml/setup-tombi/compare/v1.1.1...v1.1.2) This setup-tombi release matches [tombi v1.1.2](https://redirect.github.com/tombi-toml/tombi/releases/tag/v1.1.2). #### What's Changed - Consolidate release workflow by [@​ya7010](https://redirect.github.com/ya7010) in [#​39](https://redirect.github.com/tombi-toml/setup-tombi/pull/39) - \[codex] Link release notes to matching tombi release by [@​ya7010](https://redirect.github.com/ya7010) in [#​40](https://redirect.github.com/tombi-toml/setup-tombi/pull/40) - Bump vitest from 3.1.3 to 4.1.0 by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​41](https://redirect.github.com/tombi-toml/setup-tombi/pull/41) - Support separate binary and archive checksums by [@​ya7010](https://redirect.github.com/ya7010) in [#​43](https://redirect.github.com/tombi-toml/setup-tombi/pull/43) #### New Contributors - [@​dependabot](https://redirect.github.com/dependabot)\[bot] made their first contribution in [#​41](https://redirect.github.com/tombi-toml/setup-tombi/pull/41) **Full Changelog**: <tombi-toml/setup-tombi@v1.1.1...v1.1.2> </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - "on monday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cowprotocol/services). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMzEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjIzMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
# Description The new simulation approach for the order verification has a few limitations and we'd like to know whether an order doesn't pass the simulation because the order is just broken or because of an edge case in our simulation. # Changes This PR introduces new logic to basically turn a `CallFrame` trace into a simple easy to digest simulation report. The report only concerns itself with specific checkpoints we need to hit throughout the settlement as those should be enough to give the caller a tip where to start debugging their order (hooks, signature, wrapper setup, etc.). We are relying on a callframe tracer instead of the more detailed structopt tracer because it is significantly faster, requires less memory and still gives us enough information to infer everything we need to know in our report. ## How to test Since this code will only run in shadow mode (in a follow up PR) I only sanity checked the report for a few specific transactions.
# Description Follow up to cowprotocol#4537. In order to understand whether our simulation or the order is at fault we also need to know what went wrong while building the simulation. The most likely issue with our simulation will be that we fail to compute the necessary state overrides for the buy token balance. # Changes Instead of surfacing those issues as a hard error we simply return our best effort simulation inputs together with the state override errors. This is because a simulation can theoretically still work without the override and now that we can generate a simulation report for reverting simulations we can still get **some** important information (setup of wrappers, pre-hooks, signature check). ## How to test Rather than adding a unit test for this this logic together with the other PRs of this stack will be covered by an e2e tests asserting that orders which trigger the specific limitations of the simulation approach can still be placed.
# Description Follow up to cowprotocol#4538. This PR finally makes use of the features introduces in the previous 2 PRs to address the limitations of the simulation approach. It also addresses 2 other smaller issues with the current code. # Changes 1. We now use the state override errors and the simulation report to infer whether our state override errors caused the simulation to fail. If everything worked fine until the simulation hits the buy token transfer AND we previously failed to compute the necessary state overrides we now err on the side of allowing the order to be placed. The most relevant examples of this would be orders buying `stETH` or `xStocks` tokens as those are relatively popular and are currently not supported by our balance override code. 2. Most of the simulation disagreements I saw were caused by the new simulation filling the order more than possible. The currently active logic tries to send only 1, 10, and 100 wei of the sell token into the settlement contract (for partially fillable orders). To allow the same partially funded orders to be placed via the new logic we now chose the fill amount as `clamp(1 wei, sellToken.balanceOf(trader), full order amount)`. 3. Lastly we now also pipe the `full_balance_check` into the simulation setup which the user can opt-in to when they only want fully funded orders to be placed. Additionally this PR also starts logging the order simulation report to help us debug the remaining cases of disagreements faster. ## How to test Added a unit test for detecting and handling those edge cases of our simulation.
# Description There are use cases in which we want to allow limit order placement even if no funds are available yet. The existing logic requires the user to have at least 1 wei of balance. Reason for this is spam protection (funding a wallet requires a transaction and thus someone to spend gas). However, the same applies to setting an on-chain allowance. This PR adds logic to allow completely unfunded accounts to place limit orders as long as they have set an onchain approval. Note that the cost of doing this is roughly equivalent to transferring 1 wei of token into an account (and then using a free permit pre-hook to set allowance, which would pass today's test). Therefore, I don't expect the spam surface to increase. # Changes * When validating an order and not using a full balance check, we now have a branch if transfer fails with insufficient balance, which checks if there exists on-chain approval (without evaluating any pre hooks or wrappers) * Add and implement `allowance` method on the balance fetcher * Adjust and add a test covering this path ## How to test Added unit test and adapted e2e test ## Additional Context Context: https://nomevlabs.slack.com/archives/C0A9GFVLLD6/p1781605451078769 --------- Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> Co-authored-by: José Duarte <15343819+jmg-duarte@users.noreply.github.com>
# Description Patches [RUSTSEC-2026-0185](https://rustsec.org/advisories/RUSTSEC-2026-0185.html) reported by the `cargo audit` CI action. # Changes Updated the dependencies using `cargo audit fix`. ## How to test `cargo audit` CI action should pass again
# Description Uniswap v3 pool's ticks are i24 and liquidity_nets are i128, using BigInt incurs quite a bit of overhead, especially for i24: BigInts are (put very simply) a Vec of u64, so for each i24, we're paying 2x as much just for the number plus the vec pointer and length field, for i128 this is not *as* bad, but since we know the numbers are bounded we can do away with all this overhead. # Changes * Ticks -> i32 (we could even use alloy's I24 but i32 is simpler and more ergonomic) * Liquidity Net -> i128 ## How to test This shows before and after applying this on staging mainnet <img width="2008" height="806" alt="image" src="https://github.com/user-attachments/assets/3b309188-ec0c-4445-9fd8-2970631460e5" /> The gap between the averages is around ~10MB <img width="1023" height="399" alt="Screenshot 2026-06-23 at 15 24 17" src="https://github.com/user-attachments/assets/038a5709-a41f-44dc-b246-d8d2989bc42a" />
# Description There are some solver specific order prioritization options which can lead to the driver discarding different orders for different solvers. Figuring out whether a solver got a specific order is therefor not easily possible. There were already some logs for this but they had the default log level of `trace` (effectively always disabled) and we emitted 1 log per filtered order. # Changes Collects all discarded orders and logs them with `debug` level if at least 1 order was discarded. I chose a `BTreeMap<&'static str, Uid>` since it had the advantages of most containers with minimal downsides: * naturally grouped which leads to leaner logs * finding the correct bucket should be basically 0 overhead since no hashing is required * good cache locality Also using `&'static str` (instead of `String`) specifically means we can use the entry API without having to create a new string every time.
…col#4558) # Description The current eip 1271 verification logic returns the gas cost of the `isValidSignature()` call which gets used [here](https://github.com/cowprotocol/services/blob/f57acbaa73391dac3d27466985952c3ec7d27a5a/crates/shared/src/order_validation.rs#L850). To completely switch to the new simulation logic it also needs to support this. # Changes * added a new `Eip1271SignatureCheck` event variant which can just copy the gas cost of the function trace * adjusted the fast path to not trigger when we need to return the gas cost - otherwise we just return a gas cost of 0 ## How to test Updated the existing xdai test to now expect the new event variant and verified the gas costs are correct with tenderly
…tion to 74eedf1 (cowprotocol#4551) This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [anthropics/claude-code-action](https://redirect.github.com/anthropics/claude-code-action) | action | digest | `2fee155` → `74eedf1` | --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - "on monday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cowprotocol/services). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMzUuMCIsInVwZGF0ZWRJblZlciI6IjQzLjIzNS4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…ition (1/3) (cowprotocol#4467) # Description First PR for the streaming quote API (cowprotocol#4456). It adds the one capability the streaming endpoint needs from the pricing layer: the ability for the price-estimation competition to emit each solver's result as it arrives, rather than only the single best one once the whole competition finishes. Purely additive. Nothing consumes it yet, the next PR in the stack does. # Changes - Add a `StreamingPriceEstimating` trait next to `PriceEstimating`. - Implement it for `CompetitionEstimator`: run every estimator concurrently and yield each result as it completes, with no ranking and no early return. Verification is unaffected, the `verified` flag still rides on each estimate. # How to test New unit tests. # Related issues Part of cowprotocol#4456
# Description Our Buy/SellTokenSource enum currently supports three variants, only one of which is used in practice (ERC20). The other variants existed for a Balancer v2 specific integration (https://balancer.gitbook.io/balancer-v2/products/balancer-cow-protocol), which was used initially but has been phased out over a year ago. Any remaining use would not be genuine volume. While `Internal` was always rejected (we never completed the full integration), this PR now also phases out `External` variant and removes remaining logic for both unused variants. From the DB: - The last received `External` order in prod is from 2025-11-30 - The last traded `External` order in prod is from 2024-01-26 While fully deprecating this value is not possible due to backward compatibility constraints (existing orders and new orders share the same data model, and "removing" the old variant would cause historic orders to hash to inconsistent uids) I decided to simply block # Changes * Reject new orders/quotes if they have an unsupported source * Remove logic that was required to handle orders using unsupported sources (as well as setup/e2e tests) * Update OpenApi specs ## How to test CI ## Alternatives Considered Remove legacy orders from the DB and remove this enum type completely. Seems to intrusive though (and the remaining asserts are manageable from a complexity perspective).
…rotocol#4557) As a followup to cowprotocol#4531. This adds a bit to our ethflow native bridging test to regression proof us dropping the volume fee on these type of trades. for context see [slack](https://nomevlabs.slack.com/archives/C0361CDG8GP/p1782228399054699?thread_ts=1780672802.966959&cid=C0361CDG8GP)
This update brings the reqwest version into "sync" which will enable setting async DNS resolution for all reqwest callers
…tocol#4564) reqwest's DNS resolution is blocking by default, using getaddrinfo from the OS, when the DNS resolution is slow, this leads to increased latency in services (especially the autopilot), the async resolution allows reqwest to play nicer with tokio Enabling the feature will enable hickory by default: https://github.com/seanmonstar/reqwest/blob/ea3d9ca6877620aa571cd67246c0c37a09fdd2e8/src/async_impl/client.rs#L369 The previous OTel reqwest unification allows everything on our stack that depends on reqwest to take advantage of the async DNS Additionally, it bumps reqwest because 0.13.2 would depend on a vulnerable version of hickory (see GHSA-3v94-mw7p-v465 and GHSA-q2qq-hmj6-3wpp)
…protocol#4468) # Description Second of three stacked PRs for the streaming quote API (cowprotocol#4456). Pure refactor, no behavior change. It pulls the "build one quote from one solver estimate" logic out of `compute_quote_data` into a standalone `assemble_quote_data`, so the streaming path in the next PR can call it once per emitted solver result. Stacked on cowprotocol#4467. # Changes - Extract `assemble_quote_data` from `OrderQuoter::compute_quote_data`. The method still computes the quote expiration itself and now delegates the field assembly to the new function. # How to test Existing tests, plus new unit tests covering the extracted function on both sell and buy sides. # Related issues Part of cowprotocol#4456
# Description Third and final PR of the streaming quote API stack (cowprotocol#4456). Adds the SSE endpoint `POST /api/v1/quote/stream` that emits one quote per solver as it arrives, wiring together the competition streaming primitive (cowprotocol#4467) and the reusable quote assembly (cowprotocol#4468). Stacked on cowprotocol#4468. Compute is identical to the optimal quoter (all solvers plus verification). We change only when results are delivered, not their quality. Nothing is persisted, every event carries `id: null`, and order posting re-quotes the same way it already does for fast quotes, so `/order` is unchanged. The `priceQuality` field of `OrderQuoteRequest` is ignored on this endpoint: streaming always queries all solvers and attempts verification, emitting each result with its own `verified` flag. The field stays in the body only because the endpoint reuses `OrderQuoteRequest`. This is documented in the OpenAPI description. # Changes - Forward streaming through `SanitizedPriceEstimator` so token sanitization applies per result. - Add a `streaming_price_estimator` factory builder. - `OrderQuoter::calculate_quote_stream`: fetch gas and native prices once, then stream one quote per solver result, dropping unreasonable (zero-gas or zero-amount) estimates. - `QuoteHandler::calculate_quote_stream`: shared validation preamble, volume fee applied per event. - `POST /api/v1/quote/stream` SSE handler: validation failures return HTTP 4xx before the stream opens, per-solver errors are logged and dropped, and if no solver returns a usable quote a single terminal `error` event is sent (a `NoLiquidity` body routed through the same mapping the regular endpoint uses), otherwise the stream closes cleanly. - Wire the streaming estimator into the optimal quoter and the quote handler. - OpenAPI docs for the new endpoint, including that `priceQuality` is ignored. # How to test New unit tests across price-estimation, shared, and orderbook. A new ignored e2e smoke test (`quote_stream_smoke`). Note: `cargo check --tests -p e2e` is currently broken on `main` (pre-existing, from the `SameTokensPolicy` change in cowprotocol#4463), so the new e2e test could not be compile-verified on this branch. The unit tests and `cargo build -p orderbook` pass. # Related issues Closes cowprotocol#4456
# Description When we switched from the old gas price estimation crate to a new one built on top of alloy we lost a key optimization. The old gas price estimation updated the gas price in a background task so the total number of RPC requests was constant while they scale with the number of connected solvers and such for the new logic. For example on mainnet this causes the driver to spend a third of its RPC requests on gas price computation which is obviously insane. <img width="1187" height="304" alt="Screenshot 2026-06-29 at 09 10 08" src="https://github.com/user-attachments/assets/087a847b-6cb5-413e-ae94-681e1f1dad57" /> # Changes Implements a background task for the alloy based gas price estimator which updates the gas price once for every new block. To break up a circular dependency when creating the `Ethereum` instance in the driver I needed to move the creation of the gas price estimator into `Ethereum::new()` which in turn required a few other changes. ## How to test Added unit test Also deployed this temporarily to prod BNB and the time to convert the DTO to the domain types dropped from ~200ms to 3ms because we don't have any RPC calls on the hot path anymore. <img width="1599" height="819" alt="Screenshot 2026-06-30 at 08 26 10" src="https://github.com/user-attachments/assets/c4d00479-5826-45de-87b1-d94ff829baf1" />
# Description The log in question is creating quite a bit of noise *and* work for vector. Since auctions with id == None are quotes, and we don't really care about order 0x000...000 so there's no point in logging it. Context: https://nomevlabs.slack.com/archives/C0361CDD1FZ/p1782822341859389 # Changes * If auction is a quote, do not log unsupported orders
Bring the aave customizations onto upstream v2.368.2. - 'latest' (722c73b) is pure upstream cowprotocol/services v2.368.2. - 'main' (3878e07, 'Upgrade to v2.361.1') carries the aave customizations on an older upstream. Per decision, the result keeps upstream v2.368.2 and re-applies the aave customizations on top (MainnetFork chain + native price + baseline sources, skip_domain_separator_verification config, MAINNET_FORK contract addresses, balance-filter debug logs, and the fork CI/tooling). This matches the previously reviewed fork integration (fork/jmgd/upgrade @ 8da4f7d), whose tree is upstream v2.368.2 plus exactly this aave overlay. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.