Skip to content

Upgrade to 2.368.2#15

Open
jmg-duarte wants to merge 368 commits into
aave:mainfrom
jmg-duarte:latest
Open

Upgrade to 2.368.2#15
jmg-duarte wants to merge 368 commits into
aave:mainfrom
jmg-duarte:latest

Conversation

@jmg-duarte

Copy link
Copy Markdown

No description provided.

MartinquaXD and others added 30 commits March 4, 2026 11:51
# 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.
extrawurst and others added 30 commits June 17, 2026 11:19
…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.
[#&#8203;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.
[#&#8203;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).
[#&#8203;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
[@&#8203;yaananth](https://redirect.github.com/yaananth) in
[#&#8203;2439](https://redirect.github.com/actions/checkout/pull/2439)
- fix: expand merge commit SHA regex and add SHA-256 test cases by
[@&#8203;yaananth](https://redirect.github.com/yaananth) in
[#&#8203;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
[@&#8203;ya7010](https://redirect.github.com/ya7010) in
[#&#8203;39](https://redirect.github.com/tombi-toml/setup-tombi/pull/39)
- \[codex] Link release notes to matching tombi release by
[@&#8203;ya7010](https://redirect.github.com/ya7010) in
[#&#8203;40](https://redirect.github.com/tombi-toml/setup-tombi/pull/40)
- Bump vitest from 3.1.3 to 4.1.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot)\[bot] in
[#&#8203;41](https://redirect.github.com/tombi-toml/setup-tombi/pull/41)
- Support separate binary and archive checksums by
[@&#8203;ya7010](https://redirect.github.com/ya7010) in
[#&#8203;43](https://redirect.github.com/tombi-toml/setup-tombi/pull/43)

#### New Contributors

- [@&#8203;dependabot](https://redirect.github.com/dependabot)\[bot]
made their first contribution in
[#&#8203;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>
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.