Skip to content

Commit

Permalink
Track tokens lost in settlement contract (#2410)
Browse files Browse the repository at this point in the history
# Description
Currently we don't really know if the interactions suggested in a quote
were able to pay out the advertised amount because the interactions
actually produced the required tokens or if the settlement contract
happened to have buffers big enough to pay out any difference that might
arise.

# Changes
Track sell and buy token balance of the settlement contract before and
after the settlement.
If the settlement contract has less fewer tokens than before we at least
partly paid the quote our of our own pocket.
This PR only adds tracking and logging of these balances but does not
yet act on the difference.

Theoretically a solver could try to sell any token the settlement
contract has in its buffers (not just the sell_token) so the check is
not bullet proof but it seems to be a fair assumption for now that they
will only use the sell token balance.

## How to test
CI should continue to work and we should see the new logs.
  • Loading branch information
MartinquaXD authored Feb 20, 2024
1 parent f42eafe commit 1cb7019
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 30 deletions.
2 changes: 1 addition & 1 deletion crates/contracts/artifacts/Solver.json
Original file line number Diff line number Diff line change
@@ -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":{}}}
12 changes: 8 additions & 4 deletions crates/contracts/solidity/Solver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -42,6 +43,7 @@ contract Solver {
address payable trader,
address sellToken,
uint256 sellAmount,
address buyToken,
address nativeToken,
address payable receiver,
bytes calldata settlementCall
Expand All @@ -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;
}

Expand All @@ -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;
}
}
Loading

0 comments on commit 1cb7019

Please sign in to comment.