Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions crates/autopilot/src/arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,11 @@ pub struct Arguments {
#[clap(long, env, default_value = "false", action = clap::ArgAction::Set)]
pub disable_1271_order_sig_filter: bool,

/// Configures whether the autopilot skips balance checks for EIP-1271
/// orders.
#[clap(long, env, default_value = "false", action = clap::ArgAction::Set)]
pub disable_1271_order_balance_filter: bool,

/// Enables the usage of leader lock in the database
/// The second instance of autopilot will act as a follower
/// and not cut any auctions.
Expand Down Expand Up @@ -402,6 +407,7 @@ impl std::fmt::Display for Arguments {
max_solutions_per_solver,
db_based_solver_participation_guard,
disable_order_balance_filter,
disable_1271_order_balance_filter,
disable_1271_order_sig_filter,
enable_leader_lock,
} = self;
Expand Down Expand Up @@ -482,6 +488,10 @@ impl std::fmt::Display for Arguments {
f,
"disable_order_balance_filter: {disable_order_balance_filter}"
)?;
writeln!(
f,
"disable_1271_order_balance_filter: {disable_1271_order_balance_filter}"
)?;
writeln!(
f,
"disable_1271_order_sig_filter: {disable_1271_order_sig_filter}"
Expand Down
1 change: 1 addition & 0 deletions crates/autopilot/src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@ pub async fn run(args: Arguments, shutdown_controller: ShutdownController) {
eth.contracts().settlement().address().into_legacy(),
args.disable_order_balance_filter,
args.disable_1271_order_sig_filter,
args.disable_1271_order_balance_filter,
);

let liveness = Arc::new(Liveness::new(args.max_auction_age));
Expand Down
55 changes: 53 additions & 2 deletions crates/autopilot/src/solvable_orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ pub struct SolvableOrdersCache {
settlement_contract: H160,
disable_order_balance_filter: bool,
disable_1271_order_sig_filter: bool,
disable_1271_order_balance_filter: bool,
Copy link
Contributor

Choose a reason for hiding this comment

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

It's somewhat ambiguous now what the semantics are if balance filter is disabled but 1271 balance filter is enabled.

}

type Balances = HashMap<Query, U256>;
Expand Down Expand Up @@ -130,6 +131,7 @@ impl SolvableOrdersCache {
settlement_contract: H160,
disable_order_balance_filter: bool,
disable_1271_order_sig_filter: bool,
disable_1271_order_balance_filter: bool,
) -> Arc<Self> {
Arc::new(Self {
min_order_validity_period,
Expand All @@ -149,6 +151,7 @@ impl SolvableOrdersCache {
settlement_contract,
disable_order_balance_filter,
disable_1271_order_sig_filter,
disable_1271_order_balance_filter,
})
}

Expand Down Expand Up @@ -197,7 +200,12 @@ impl SolvableOrdersCache {
let orders = if self.disable_order_balance_filter {
orders
} else {
let orders = orders_with_balance(orders, &balances, self.settlement_contract);
let orders = orders_with_balance(
orders,
&balances,
self.settlement_contract,
self.disable_1271_order_balance_filter,
);
let removed = counter.checkpoint("insufficient_balance", &orders);
invalid_order_uids.extend(removed);

Expand Down Expand Up @@ -539,10 +547,15 @@ fn orders_with_balance(
mut orders: Vec<Order>,
balances: &Balances,
settlement_contract: H160,
disable_1271_order_balance_filter: bool,
) -> Vec<Order> {
// Prefer newer orders over older ones.
orders.sort_by_key(|order| std::cmp::Reverse(order.metadata.creation_date));
orders.retain(|order| {
if disable_1271_order_balance_filter && matches!(order.signature, Signature::Eip1271(_)) {
return true;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Seeing the code block below really makes me think we should detect this based on flashloan hints in app data rather than these flags. It looks like full_app_data is available on the order and there is already a Validator component used for adding the partner fee logic that is able to parse the app data in the autopilot.

Copy link

@anxolin anxolin Nov 12, 2025

Choose a reason for hiding this comment

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

Using the hint would help.

Is long-term an option to just simulate the pre-hook and to understand how it credits and deploys the helper?

if order.data.receiver.as_ref() == Some(&settlement_contract) {
// TODO: replace with proper detection logic
// for now we assume that all orders with the settlement contract
Expand Down Expand Up @@ -1481,14 +1494,52 @@ mod tests {
.collect();
let expected = &[0, 2, 4];

let filtered = orders_with_balance(orders.clone(), &balances, settlement_contract);
let filtered = orders_with_balance(orders.clone(), &balances, settlement_contract, false);
assert_eq!(filtered.len(), expected.len());
for index in expected {
let found = filtered.iter().any(|o| o.data == orders[*index].data);
assert!(found, "{}", index);
}
}

#[test]
fn eip1271_orders_can_skip_balance_filtering() {
let settlement_contract = H160([1; 20]);
let eip1271_order = Order {
data: OrderData {
sell_token: H160::from_low_u64_be(7),
sell_amount: 10.into(),
fee_amount: 5.into(),
partially_fillable: false,
..Default::default()
},
signature: Signature::Eip1271(vec![1, 2, 3]),
..Default::default()
};
let regular_order = Order {
data: OrderData {
sell_token: H160::from_low_u64_be(8),
sell_amount: 10.into(),
fee_amount: 5.into(),
partially_fillable: false,
..Default::default()
},
..Default::default()
};

let orders = vec![regular_order.clone(), eip1271_order.clone()];
let balances: Balances = Default::default();

let filtered = orders_with_balance(orders.clone(), &balances, settlement_contract, true);
// 1721 filter is turned disabled, only the regular order is filtered out
assert_eq!(filtered.len(), 1);
assert!(matches!(filtered[0].signature, Signature::Eip1271(_)));

let filtered_without_override =
orders_with_balance(orders, &balances, settlement_contract, false);
assert!(filtered_without_override.is_empty());
}

#[test]
fn prioritizes_missing_prices() {
let now = chrono::Utc::now();
Expand Down
Loading