Skip to content

Fix haircut logic#4093

Merged
squadgazzz merged 6 commits intomainfrom
fix-haircut-logic
Jan 29, 2026
Merged

Fix haircut logic#4093
squadgazzz merged 6 commits intomainfrom
fix-haircut-logic

Conversation

@squadgazzz
Copy link
Copy Markdown
Contributor

@squadgazzz squadgazzz commented Jan 27, 2026

Description

The haircut feature had a critical bug where the driver-reported sell_amount would exceed the user's signed one. For example:

  • User signed: sell_amount = 5 ETH
  • Solver proposed a solution with the same sell amount
  • Driver reported: sellAmount = 5.25 ETH (with 5% haircut added)
  • The settlement executed onchain, but autopilot couldn't make sense of it due to the unexpected sell amount
  • The circuit breaker also detects this and bans the solver

Changes

  1. Removed haircut from sell_amount() - Now returns only executed + fee, which is the actual amount that left the user's wallet
  2. Added haircut_in_sell_token() helper - Computes haircut amount converted to sell token
  3. Updated custom_prices() - Applies haircut only for quotes/scoring purposes, making bids more conservative without affecting reported amounts
  4. Added Jit::custom_prices() - JIT orders don't have a haircut (for now), so they use simple sell/buy amount derivation

How to test

Adjusted existing and added new tests that fail on the main branch, but work with the fix.

@squadgazzz squadgazzz marked this pull request as ready for review January 27, 2026 17:05
@squadgazzz squadgazzz requested a review from a team as a code owner January 27, 2026 17:05
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

The pull request effectively addresses the critical bug where the driver-reported sell_amount could exceed the user's signed amount due to haircut logic. The changes correctly separate the haircut application for scoring purposes from the actual executed amounts, ensuring that sell_amount() returns only executed + fee. The introduction of haircut_in_sell_token() and Jit::custom_prices() are well-implemented to support this new logic. The updated and new tests provide good coverage for both sell and buy orders with haircut, verifying the fix and ensuring correct behavior. No critical issues were found in this review.

Copy link
Copy Markdown
Contributor

@MartinquaXD MartinquaXD left a comment

Choose a reason for hiding this comment

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

The change makes sense to me. Rather than announcing that a higher sell amount will leave the user's balance this only adjusts the custom prices.
Also the test where you assert that the autopilot is able to index the settlement correctly gives me high confidence that this is correct as the autopilot complained for the same reason the circuit breaker did. 👍

Comment thread crates/driver/src/tests/cases/haircut.rs Outdated
Comment thread crates/e2e/tests/e2e/limit_orders.rs Outdated
@squadgazzz squadgazzz added this pull request to the merge queue Jan 29, 2026
Merged via the queue into main with commit 7fb5cc4 Jan 29, 2026
19 checks passed
@squadgazzz squadgazzz deleted the fix-haircut-logic branch January 29, 2026 15:21
@github-actions github-actions Bot locked and limited conversation to collaborators Jan 29, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants