diff --git a/crates/driver/src/domain/competition/solution/settlement.rs b/crates/driver/src/domain/competition/solution/settlement.rs index 4f52311307..8fd3111928 100644 --- a/crates/driver/src/domain/competition/solution/settlement.rs +++ b/crates/driver/src/domain/competition/solution/settlement.rs @@ -280,10 +280,10 @@ impl Settlement { buy: trade.buy(), executed_sell: trade .sell_amount(&prices) - .unwrap_or_else(|err| log_err(trade, err, "sell_amount")), + .unwrap_or_else(|err| log_err(trade, err, "executed_sell")), executed_buy: trade .buy_amount(&prices) - .unwrap_or_else(|err| log_err(trade, err, "buy_amount")), + .unwrap_or_else(|err| log_err(trade, err, "executed_buy")), } } Trade::Jit(jit) => competition::Amounts { @@ -292,10 +292,10 @@ impl Settlement { buy: trade.buy(), executed_sell: jit .executed_sell() - .unwrap_or_else(|err| log_err(trade, err, "sell_amount")), + .unwrap_or_else(|err| log_err(trade, err, "executed_sell")), executed_buy: jit .executed_buy() - .unwrap_or_else(|err| log_err(trade, err, "buy_amount")), + .unwrap_or_else(|err| log_err(trade, err, "executed_buy")), }, }; acc.insert(trade.uid(), order); diff --git a/crates/driver/src/tests/cases/jit_orders.rs b/crates/driver/src/tests/cases/jit_orders.rs index 09ae7bb3e7..243b709b83 100644 --- a/crates/driver/src/tests/cases/jit_orders.rs +++ b/crates/driver/src/tests/cases/jit_orders.rs @@ -13,6 +13,7 @@ use crate::{ ab_order, ab_solution, test_solver, + ExpectedOrderAmounts, Test, }, }, @@ -62,6 +63,18 @@ async fn protocol_fee_test_case(test_case: TestCase) { .buy_amount(test_case.execution.solver.buy); let pool = ab_adjusted_pool(quote); let solver_fee = test_case.execution.driver.sell / 100; + // Amounts expected to be returned by the driver after fee processing + let jit_order_expected_amounts = if test_case.is_surplus_capturing_jit_order { + ExpectedOrderAmounts { + sell: test_case.execution.solver.sell, + buy: test_case.execution.solver.buy, + } + } else { + ExpectedOrderAmounts { + sell: test_case.solution.jit_order.order.sell_amount, + buy: test_case.solution.jit_order.order.buy_amount, + } + }; let jit_order = setup::JitOrder { order: ab_order() @@ -70,7 +83,8 @@ async fn protocol_fee_test_case(test_case: TestCase) { .buy_amount(test_case.solution.jit_order.order.buy_amount) .solver_fee(Some(solver_fee)) .side(test_case.solution.jit_order.order.side) - .no_surplus(), + .no_surplus() + .expected_amounts(jit_order_expected_amounts), }; let order = ab_order() diff --git a/crates/driver/src/tests/setup/mod.rs b/crates/driver/src/tests/setup/mod.rs index afe7e6037a..96ba9e8e7b 100644 --- a/crates/driver/src/tests/setup/mod.rs +++ b/crates/driver/src/tests/setup/mod.rs @@ -27,6 +27,7 @@ use { DEFAULT_SURPLUS_FACTOR, ETH_ORDER_AMOUNT, }, + hex_address, setup::blockchain::{Blockchain, Trade}, }, }, @@ -1236,29 +1237,33 @@ impl<'a> SolveOk<'a> { // Since JIT orders don't have UID at creation time, we need to search for // matching token pair for expected in jit_orders.iter() { + let mut exist = false; for trade in trades.values() { - let u256 = |value: &serde_json::Value| { - eth::U256::from_dec_str(value.as_str().unwrap()).unwrap() - }; - let sell_token = trade.get("sellToken").unwrap().to_string(); - let buy_token = trade.get("buyToken").unwrap().to_string(); - - if sell_token == expected.order.sell_token && buy_token == expected.order.buy_token - { - assert!(is_approximately_equal( - expected.order.sell_amount, - u256(trade.get("executedSell").unwrap()) - )); - assert!(is_approximately_equal( - expected.order.buy_amount.unwrap(), - u256(trade.get("executedBuy").unwrap()) - )); - } + exist |= self.exist_jit_order(trade, expected) } + assert!(exist, "JIT order {expected:?} not found"); } self } + /// Find for a JIT order, given specific token pair and buy/sell amount, + /// return true if the JIT order was found + fn exist_jit_order(&self, trade: &serde_json::Value, expected: &JitOrder) -> bool { + let u256 = + |value: &serde_json::Value| eth::U256::from_dec_str(value.as_str().unwrap()).unwrap(); + let sell_token = trade.get("sellToken").unwrap().to_string(); + let sell_token = sell_token.trim_matches('"'); + let buy_token = trade.get("buyToken").unwrap().to_string(); + let buy_token = buy_token.trim_matches('"'); + let sell_amount = u256(trade.get("executedSell").unwrap()); + let buy_amount = u256(trade.get("executedBuy").unwrap()); + + sell_token == hex_address(self.blockchain.get_token(&expected.order.sell_token)) + && buy_token == hex_address(self.blockchain.get_token(&expected.order.buy_token)) + && expected.order.expected_amounts.clone().unwrap().sell == sell_amount + && expected.order.expected_amounts.clone().unwrap().buy == buy_amount + } + /// Check that the solution contains the expected orders. pub fn orders(self, orders: &[Order]) -> Self { let solution = self.solution(); diff --git a/crates/driver/src/tests/setup/solver.rs b/crates/driver/src/tests/setup/solver.rs index 0939f734c6..c4e0e00fbd 100644 --- a/crates/driver/src/tests/setup/solver.rs +++ b/crates/driver/src/tests/setup/solver.rs @@ -197,20 +197,24 @@ impl Solver { }) }, )); - prices_json.insert( - config - .blockchain - .get_token_wrapped(fulfillment.quoted_order.order.sell_token), - fulfillment.execution.buy.to_string(), - ); - prices_json.insert( - config - .blockchain - .get_token_wrapped(fulfillment.quoted_order.order.buy_token), - (fulfillment.execution.sell - - fulfillment.quoted_order.order.surplus_fee()) - .to_string(), - ); + assert!(prices_json + .insert( + config + .blockchain + .get_token_wrapped(fulfillment.quoted_order.order.sell_token), + fulfillment.execution.buy.to_string(), + ) + .is_none()); + assert!(prices_json + .insert( + config + .blockchain + .get_token_wrapped(fulfillment.quoted_order.order.buy_token), + (fulfillment.execution.sell + - fulfillment.quoted_order.order.surplus_fee()) + .to_string(), + ) + .is_none()); { // trades have optional field `fee` let order = if config.quote { @@ -275,19 +279,23 @@ impl Solver { .expected_surplus_capturing_jit_order_owners .contains(&jit.quoted_order.order.owner) { - prices_json.insert( - config - .blockchain - .get_token_wrapped(jit.quoted_order.order.sell_token), - jit.execution.buy.to_string(), - ); - prices_json.insert( - config - .blockchain - .get_token_wrapped(jit.quoted_order.order.buy_token), - (jit.execution.sell - jit.quoted_order.order.surplus_fee()) - .to_string(), - ); + assert!(prices_json + .insert( + config + .blockchain + .get_token_wrapped(jit.quoted_order.order.sell_token), + jit.execution.buy.to_string(), + ) + .is_none()); + assert!(prices_json + .insert( + config + .blockchain + .get_token_wrapped(jit.quoted_order.order.buy_token), + (jit.execution.sell - jit.quoted_order.order.surplus_fee()) + .to_string(), + ) + .is_none()); } { let executed_amount = match jit.quoted_order.order.executed {