diff --git a/crates/contracts/artifacts/Solver.json b/crates/contracts/artifacts/Solver.json index e93eb9b7f2..5adf514a33 100644 --- a/crates/contracts/artifacts/Solver.json +++ b/crates/contracts/artifacts/Solver.json @@ -1 +1 @@ -{"abi":[{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"storeBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISettlement","name":"settlementContract","type":"address"},{"internalType":"address payable","name":"trader","type":"address"},{"internalType":"address","name":"sellToken","type":"address"},{"internalType":"uint256","name":"sellAmount","type":"uint256"},{"internalType":"address","name":"nativeToken","type":"address"},{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"bytes","name":"settlementCall","type":"bytes"}],"name":"swap","outputs":[{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256[]","name":"queriedBalances","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"}],"bytecode":"0x608060405234801561001057600080fd5b5061069d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806351a937b01461003b578063aee8d1f714610065575b600080fd5b61004e61004936600461048d565b61007a565b60405161005c929190610566565b60405180910390f35b6100786100733660046105b4565b610284565b005b60006060333014610111576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f6f6e6c792073696d756c6174696f6e206c6f67696320697320616c6c6f77656460448201527f20746f2063616c6c202773776170272066756e6374696f6e0000000000000000606482015260840160405180910390fd5b6040517f66b00f6800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b81166004830152898116602483015260448201899052878116606483015286811660848301528a16906366b00f689060a401600060405180830381600087803b15801561019957600080fd5b505af11580156101ad573d6000803e3d6000fd5b5050505060005a905061020d85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505073ffffffffffffffffffffffffffffffffffffffff8f16929150506103cd565b506000545a61021c908361061c565b610226919061061c565b600180546040805160208084028201810190925282815293965083018282801561026f57602002820191906000526020600020905b81548152602001906001019080831161025b575b50505050509150509850989650505050505050565b60005a9050600173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff851614610351576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301528516906370a0823190602401602060405180830381865afa158015610328573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034c9190610635565b61036a565b8273ffffffffffffffffffffffffffffffffffffffff16315b815460018181018455600093845260208420909101919091558054146103925761116c610396565b61342b5b61ffff169050805a6103a8908461061c565b6103b2919061064e565b6000808282546103c2919061064e565b909155505050505050565b60606103db836000846103e2565b9392505050565b606060008473ffffffffffffffffffffffffffffffffffffffff16848460405161040c9190610661565b60006040518083038185875af1925050503d8060008114610449576040519150601f19603f3d011682016040523d82523d6000602084013e61044e565b606091505b50925090508061046057815160208301fd5b509392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461048a57600080fd5b50565b60008060008060008060008060e0898b0312156104a957600080fd5b88356104b481610468565b975060208901356104c481610468565b965060408901356104d481610468565b95506060890135945060808901356104eb81610468565b935060a08901356104fb81610468565b925060c089013567ffffffffffffffff8082111561051857600080fd5b818b0191508b601f83011261052c57600080fd5b81358181111561053b57600080fd5b8c602082850101111561054d57600080fd5b6020830194508093505050509295985092959890939650565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156105a75784518352938301939183019160010161058b565b5090979650505050505050565b600080604083850312156105c757600080fd5b82356105d281610468565b915060208301356105e281610468565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561062f5761062f6105ed565b92915050565b60006020828403121561064757600080fd5b5051919050565b8082018082111561062f5761062f6105ed565b6000825160005b818110156106825760208186018101518583015201610668565b50600092019182525091905056fea164736f6c6343000811000a","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c806351a937b01461003b578063aee8d1f714610065575b600080fd5b61004e61004936600461048d565b61007a565b60405161005c929190610566565b60405180910390f35b6100786100733660046105b4565b610284565b005b60006060333014610111576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f6f6e6c792073696d756c6174696f6e206c6f67696320697320616c6c6f77656460448201527f20746f2063616c6c202773776170272066756e6374696f6e0000000000000000606482015260840160405180910390fd5b6040517f66b00f6800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b81166004830152898116602483015260448201899052878116606483015286811660848301528a16906366b00f689060a401600060405180830381600087803b15801561019957600080fd5b505af11580156101ad573d6000803e3d6000fd5b5050505060005a905061020d85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505073ffffffffffffffffffffffffffffffffffffffff8f16929150506103cd565b506000545a61021c908361061c565b610226919061061c565b600180546040805160208084028201810190925282815293965083018282801561026f57602002820191906000526020600020905b81548152602001906001019080831161025b575b50505050509150509850989650505050505050565b60005a9050600173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff851614610351576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301528516906370a0823190602401602060405180830381865afa158015610328573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034c9190610635565b61036a565b8273ffffffffffffffffffffffffffffffffffffffff16315b815460018181018455600093845260208420909101919091558054146103925761116c610396565b61342b5b61ffff169050805a6103a8908461061c565b6103b2919061064e565b6000808282546103c2919061064e565b909155505050505050565b60606103db836000846103e2565b9392505050565b606060008473ffffffffffffffffffffffffffffffffffffffff16848460405161040c9190610661565b60006040518083038185875af1925050503d8060008114610449576040519150601f19603f3d011682016040523d82523d6000602084013e61044e565b606091505b50925090508061046057815160208301fd5b509392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461048a57600080fd5b50565b60008060008060008060008060e0898b0312156104a957600080fd5b88356104b481610468565b975060208901356104c481610468565b965060408901356104d481610468565b95506060890135945060808901356104eb81610468565b935060a08901356104fb81610468565b925060c089013567ffffffffffffffff8082111561051857600080fd5b818b0191508b601f83011261052c57600080fd5b81358181111561053b57600080fd5b8c602082850101111561054d57600080fd5b6020830194508093505050509295985092959890939650565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156105a75784518352938301939183019160010161058b565b5090979650505050505050565b600080604083850312156105c757600080fd5b82356105d281610468565b915060208301356105e281610468565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561062f5761062f6105ed565b92915050565b60006020828403121561064757600080fd5b5051919050565b8082018082111561062f5761062f6105ed565b6000825160005b818110156106825760208186018101518583015201610668565b50600092019182525091905056fea164736f6c6343000811000a","devdoc":{"methods":{}},"userdoc":{"methods":{}}} +{"abi":[{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"storeBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISettlement","name":"settlementContract","type":"address"},{"internalType":"address payable","name":"trader","type":"address"},{"internalType":"address","name":"sellToken","type":"address"},{"internalType":"uint256","name":"sellAmount","type":"uint256"},{"internalType":"address","name":"buyToken","type":"address"},{"internalType":"address","name":"nativeToken","type":"address"},{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"bytes","name":"settlementCall","type":"bytes"}],"name":"swap","outputs":[{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256[]","name":"queriedBalances","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"}],"bytecode":"0x608060405234801561001057600080fd5b506108cd806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806329055e4f1461003b578063aee8d1f714610065575b600080fd5b61004e6100493660046106aa565b61007a565b60405161005c929190610796565b60405180910390f35b6100786100733660046107e4565b6104bd565b005b60006060333014610111576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f6f6e6c792073696d756c6174696f6e206c6f67696320697320616c6c6f77656460448201527f20746f2063616c6c202773776170272066756e6374696f6e0000000000000000606482015260840160405180910390fd5b6040517f66b00f6800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c811660048301528a81166024830152604482018a9052878116606483015286811660848301528b16906366b00f689060a401600060405180830381600087803b15801561019957600080fd5b505af11580156101ad573d6000803e3d6000fd5b50506040517faee8d1f700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808d1660048301528e16602482015230925063aee8d1f79150604401600060405180830381600087803b15801561022057600080fd5b505af1158015610234573d6000803e3d6000fd5b50506040517faee8d1f700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808b1660048301528e16602482015230925063aee8d1f79150604401600060405180830381600087803b1580156102a757600080fd5b505af11580156102bb573d6000803e3d6000fd5b5050505060005a905061033185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d73ffffffffffffffffffffffffffffffffffffffff166105ea90919063ffffffff16565b506000545a610340908361084c565b61034a919061084c565b6040517faee8d1f700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c811660048301528e166024820152909350309063aee8d1f790604401600060405180830381600087803b1580156103bc57600080fd5b505af11580156103d0573d6000803e3d6000fd5b50506040517faee8d1f700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b811660048301528f16602482015230925063aee8d1f79150604401600060405180830381600087803b15801561044357600080fd5b505af1158015610457573d6000803e3d6000fd5b5050505060018054806020026020016040519081016040528092919081815260200182805480156104a757602002820191906000526020600020905b815481526020019060010190808311610493575b5050505050915050995099975050505050505050565b60005a9050600173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff85161461058a576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301528516906370a0823190602401602060405180830381865afa158015610561573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105859190610865565b6105a3565b8273ffffffffffffffffffffffffffffffffffffffff16315b815460018101835560009283526020909220909101555a6105c4908261084c565b6105d09061116c61087e565b6000808282546105e0919061087e565b9091555050505050565b60606105f8836000846105ff565b9392505050565b606060008473ffffffffffffffffffffffffffffffffffffffff1684846040516106299190610891565b60006040518083038185875af1925050503d8060008114610666576040519150601f19603f3d011682016040523d82523d6000602084013e61066b565b606091505b50925090508061067d57815160208301fd5b509392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146106a757600080fd5b50565b60008060008060008060008060006101008a8c0312156106c957600080fd5b89356106d481610685565b985060208a01356106e481610685565b975060408a01356106f481610685565b965060608a0135955060808a013561070b81610685565b945060a08a013561071b81610685565b935060c08a013561072b81610685565b925060e08a013567ffffffffffffffff8082111561074857600080fd5b818c0191508c601f83011261075c57600080fd5b81358181111561076b57600080fd5b8d602082850101111561077d57600080fd5b6020830194508093505050509295985092959850929598565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156107d7578451835293830193918301916001016107bb565b5090979650505050505050565b600080604083850312156107f757600080fd5b823561080281610685565b9150602083013561081281610685565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561085f5761085f61081d565b92915050565b60006020828403121561087757600080fd5b5051919050565b8082018082111561085f5761085f61081d565b6000825160005b818110156108b25760208186018101518583015201610898565b50600092019182525091905056fea164736f6c6343000811000a","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c806329055e4f1461003b578063aee8d1f714610065575b600080fd5b61004e6100493660046106aa565b61007a565b60405161005c929190610796565b60405180910390f35b6100786100733660046107e4565b6104bd565b005b60006060333014610111576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f6f6e6c792073696d756c6174696f6e206c6f67696320697320616c6c6f77656460448201527f20746f2063616c6c202773776170272066756e6374696f6e0000000000000000606482015260840160405180910390fd5b6040517f66b00f6800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c811660048301528a81166024830152604482018a9052878116606483015286811660848301528b16906366b00f689060a401600060405180830381600087803b15801561019957600080fd5b505af11580156101ad573d6000803e3d6000fd5b50506040517faee8d1f700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808d1660048301528e16602482015230925063aee8d1f79150604401600060405180830381600087803b15801561022057600080fd5b505af1158015610234573d6000803e3d6000fd5b50506040517faee8d1f700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808b1660048301528e16602482015230925063aee8d1f79150604401600060405180830381600087803b1580156102a757600080fd5b505af11580156102bb573d6000803e3d6000fd5b5050505060005a905061033185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d73ffffffffffffffffffffffffffffffffffffffff166105ea90919063ffffffff16565b506000545a610340908361084c565b61034a919061084c565b6040517faee8d1f700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c811660048301528e166024820152909350309063aee8d1f790604401600060405180830381600087803b1580156103bc57600080fd5b505af11580156103d0573d6000803e3d6000fd5b50506040517faee8d1f700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b811660048301528f16602482015230925063aee8d1f79150604401600060405180830381600087803b15801561044357600080fd5b505af1158015610457573d6000803e3d6000fd5b5050505060018054806020026020016040519081016040528092919081815260200182805480156104a757602002820191906000526020600020905b815481526020019060010190808311610493575b5050505050915050995099975050505050505050565b60005a9050600173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff85161461058a576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301528516906370a0823190602401602060405180830381865afa158015610561573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105859190610865565b6105a3565b8273ffffffffffffffffffffffffffffffffffffffff16315b815460018101835560009283526020909220909101555a6105c4908261084c565b6105d09061116c61087e565b6000808282546105e0919061087e565b9091555050505050565b60606105f8836000846105ff565b9392505050565b606060008473ffffffffffffffffffffffffffffffffffffffff1684846040516106299190610891565b60006040518083038185875af1925050503d8060008114610666576040519150601f19603f3d011682016040523d82523d6000602084013e61066b565b606091505b50925090508061067d57815160208301fd5b509392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146106a757600080fd5b50565b60008060008060008060008060006101008a8c0312156106c957600080fd5b89356106d481610685565b985060208a01356106e481610685565b975060408a01356106f481610685565b965060608a0135955060808a013561070b81610685565b945060a08a013561071b81610685565b935060c08a013561072b81610685565b925060e08a013567ffffffffffffffff8082111561074857600080fd5b818c0191508c601f83011261075c57600080fd5b81358181111561076b57600080fd5b8d602082850101111561077d57600080fd5b6020830194508093505050509295985092959850929598565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156107d7578451835293830193918301916001016107bb565b5090979650505050505050565b600080604083850312156107f757600080fd5b823561080281610685565b9150602083013561081281610685565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561085f5761085f61081d565b92915050565b60006020828403121561087757600080fd5b5051919050565b8082018082111561085f5761085f61081d565b6000825160005b818110156108b25760208186018101518583015201610898565b50600092019182525091905056fea164736f6c6343000811000a","devdoc":{"methods":{}},"userdoc":{"methods":{}}} diff --git a/crates/contracts/solidity/Solver.sol b/crates/contracts/solidity/Solver.sol index 495622a5d8..791da21f48 100644 --- a/crates/contracts/solidity/Solver.sol +++ b/crates/contracts/solidity/Solver.sol @@ -31,6 +31,7 @@ contract Solver { /// @param trader - address of the order owner doing the trade /// @param sellToken - address of the token being sold /// @param sellAmount - amount being sold + /// @param buyToken - address of the token being bought /// @param nativeToken - ERC20 version of the chain's token /// @param receiver - address receiving the bought tokens /// @param settlementCall - the calldata of the `settle()` call @@ -42,6 +43,7 @@ contract Solver { address payable trader, address sellToken, uint256 sellAmount, + address buyToken, address nativeToken, address payable receiver, bytes calldata settlementCall @@ -53,10 +55,14 @@ contract Solver { // Prepare the trade in the context of the trader so we are allowed // to set approvals and things like that. Trader(trader).prepareSwap(settlementContract, sellToken, sellAmount, nativeToken, receiver); + this.storeBalance(sellToken, address(settlementContract)); + this.storeBalance(buyToken, address(settlementContract)); uint256 gasStart = gasleft(); // TODO can we assume the overhead of this function call to be negligible due to inlining? address(settlementContract).doCall(settlementCall); gasUsed = gasStart - gasleft() - _simulationOverhead; + this.storeBalance(sellToken, address(settlementContract)); + this.storeBalance(buyToken, address(settlementContract)); queriedBalances = _queriedBalances; } @@ -72,9 +78,7 @@ contract Solver { ? owner.balance : IERC20(token).balanceOf(owner) ); - // Account for costs of gas used outside of metered section. Noting that - // reading cold storage costs more which results in higher overhead for the first call - uint256 measurementOverhead = _queriedBalances.length == 1 ? 13355 : 4460; - _simulationOverhead += gasStart - gasleft() + measurementOverhead; + // Account for costs of gas used outside of metered section. + _simulationOverhead += gasStart - gasleft() + 4460; } } diff --git a/crates/shared/src/price_estimation/trade_verifier.rs b/crates/shared/src/price_estimation/trade_verifier.rs index 504be72b59..355120c9ce 100644 --- a/crates/shared/src/price_estimation/trade_verifier.rs +++ b/crates/shared/src/price_estimation/trade_verifier.rs @@ -22,7 +22,7 @@ use { order::{OrderData, OrderKind, BUY_ETH_ADDRESS}, signature::{Signature, SigningScheme}, }, - number::nonzero::U256 as NonZeroU256, + number::{conversions::u256_to_big_int, nonzero::U256 as NonZeroU256}, std::sync::Arc, web3::{ethabi::Token, types::CallRequest}, }; @@ -127,6 +127,7 @@ impl TradeVerifying for TradeVerifier { verification.from, query.sell_token, sell_amount, + query.buy_token, self.native_token, verification.receiver, Bytes(settlement.data.unwrap().0), @@ -176,18 +177,18 @@ impl TradeVerifying for TradeVerifier { .simulate(call, overrides, Some(block)) .await .context("failed to simulate quote")?; - let summary = - SettleOutput::decode(&output).context("could not decode simulation output")?; + let summary = SettleOutput::decode(&output, query.kind) + .context("could not decode simulation output")?; let verified = VerifiedEstimate { - out_amount: summary - .out_amount(query.kind) - .context("could not compute out_amount")?, + out_amount: summary.out_amount, gas: summary.gas_used.as_u64(), solver: trade.solver, }; tracing::debug!( out_diff = ?trade.out_amount.abs_diff(verified.out_amount), gas_diff = ?trade.gas_estimate.abs_diff(verified.gas), + lost_buy_amount = ?summary.buy_tokens_diff, + lost_sell_amount = ?summary.sell_tokens_diff, time = ?start.elapsed(), promised_out_amount = ?trade.out_amount, promised_gas = trade.gas_estimate, @@ -306,39 +307,51 @@ fn add_balance_queries( settlement } -/// Output of `Trader::settle` smart contract call. +/// Analyzed output of `Solver::settle` smart contract call. #[derive(Debug)] struct SettleOutput { /// Gas used for the `settle()` call. gas_used: U256, - /// Balances queried during the simulation in the order specified during the - /// simulation set up. - queried_balances: Vec, + /// `out_amount` perceived by the trader (sell token for buy orders or buy + /// token for sell order) + out_amount: U256, + /// Difference in buy tokens of the settlement contract before and after the + /// trade. + buy_tokens_diff: num::BigInt, + /// Difference in sell tokens of the settlement contract before and after + /// the trade. + sell_tokens_diff: num::BigInt, } impl SettleOutput { - fn decode(output: &[u8]) -> Result { + fn decode(output: &[u8], kind: OrderKind) -> Result { let function = Solver::raw_contract().abi.function("swap").unwrap(); let tokens = function.decode_output(output).context("decode")?; - let (gas_used, queried_balances) = Tokenize::from_token(Token::Tuple(tokens))?; - Ok(Self { - gas_used, - queried_balances, - }) - } + let (gas_used, balances): (U256, Vec) = Tokenize::from_token(Token::Tuple(tokens))?; + + let settlement_sell_balance_before = u256_to_big_int(&balances[0]); + let settlement_buy_balance_before = u256_to_big_int(&balances[1]); + + let trader_balance_before = balances[2]; + let trader_balance_after = balances[3]; + + let settlement_sell_balance_after = u256_to_big_int(&balances[4]); + let settlement_buy_balance_after = u256_to_big_int(&balances[5]); - /// Computes the actual [`Trade::out_amount`] based on the simulation. - fn out_amount(&self, kind: OrderKind) -> Result { - let balances = &self.queried_balances; - let balance_before = balances.first().context("no balance before settlement")?; - let balance_after = balances.get(1).context("no balance after settlement")?; let out_amount = match kind { // for sell orders we track the buy_token amount which increases during the settlement - OrderKind::Sell => balance_after.checked_sub(*balance_before), + OrderKind::Sell => trader_balance_after.checked_sub(trader_balance_before), // for buy orders we track the sell_token amount which decreases during the settlement - OrderKind::Buy => balance_before.checked_sub(*balance_after), + OrderKind::Buy => trader_balance_before.checked_sub(trader_balance_after), }; - out_amount.context("underflow during out_amount computation") + let out_amount = out_amount.context("underflow during out_amount computation")?; + + Ok(SettleOutput { + gas_used, + out_amount, + buy_tokens_diff: settlement_buy_balance_before - settlement_buy_balance_after, + sell_tokens_diff: settlement_sell_balance_before - settlement_sell_balance_after, + }) } }