From a520f40182e085fd222f063610f01c0e1a15a81b Mon Sep 17 00:00:00 2001 From: Martin Magnus Date: Fri, 13 Dec 2024 13:52:23 +0100 Subject: [PATCH] Verify quote with pre interactions (#3160) # Description Not too long ago https://github.com/cowprotocol/services/pull/3081 changed the simulation logic to not do any set up steps on behalf of the user if the quote provided some pre-interactions. That was done to avoid reverts when a pre-interactions actually set up everything for the trade (e.g. get balances by unstaking). However, this caused issues with verifying quotes with `permit` pre-interactions. Because the quote provided the `permit` pre-interaction the simulation logic also did not try to fake balances although it could have. # Changes Now we again always call the code to setup approvals and such BUT we do it as the very last `pre-interaction`. That way this operation becomes a no-op if the user already sets up everything with their pre-interactions OR does the usual logic and reverts with helpful error messages if the pre-conditions can't be met. Since this function may now be a no-op I renamed it to `ensureSwapPreconditions()`. Additionally this moves code that was previously run before the settlement inside the settlement which increases the measured gas cost. To work around that I also introduced a wrapper function in `Solver.sol` that simply calls the `Trader` function and discounts the gas costs. Note that we can't simply do the necessary steps in the `Solver` because we need to be inside the context of the `Trader` to be able to set approvals and such. That way we can verify quotes which do no, partial or the entire swap setup in their pre-interactions while keeping good error messages and accurate gas estimates. Kudos to @nlordell for the idea. ## How to test I added an e2e test that fails without the PR. --- crates/contracts/artifacts/Solver.json | 2 +- crates/contracts/artifacts/Trader.json | 2 +- crates/contracts/solidity/Solver.sol | 57 ++++++-------- crates/contracts/solidity/Trader.sol | 11 ++- crates/e2e/tests/e2e/quote_verification.rs | 35 +++++++++ .../src/price_estimation/trade_verifier.rs | 77 +++++++++++++------ 6 files changed, 123 insertions(+), 61 deletions(-) diff --git a/crates/contracts/artifacts/Solver.json b/crates/contracts/artifacts/Solver.json index 19639cbd96..a046d11cdf 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"},{"internalType":"bool","name":"countGas","type":"bool"}],"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[]","name":"tokens","type":"address[]"},{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"bytes","name":"settlementCall","type":"bytes"},{"components":[{"internalType":"bool","name":"enabled","type":"bool"},{"internalType":"address","name":"spardose","type":"address"}],"internalType":"struct Solver.Mock","name":"mock","type":"tuple"}],"name":"swap","outputs":[{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256[]","name":"queriedBalances","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"}],"bytecode":"0x608060405234801561001057600080fd5b506109e0806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806317b86b161461003b5780633bbb2e1d14610065575b600080fd5b61004e61004936600461072c565b61007a565b60405161005c929190610817565b60405180910390f35b610078610073366004610865565b6102aa565b005b60006060333014610111576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f6f6e6c792073696d756c6174696f6e206c6f67696320697320616c6c6f77656460448201527f20746f2063616c6c202773776170272066756e6374696f6e0000000000000000606482015260840160405180910390fd5b8251156101bf5760208301516040517f66b00f6800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8f811660048301528d81166024830152604482018d90528b811660648301529182166084820152908d16906366b00f689060a401600060405180830381600087803b1580156101a657600080fd5b505af11580156101ba573d6000803e3d6000fd5b505050505b60008673ffffffffffffffffffffffffffffffffffffffff16600060405160006040518083038185875af1925050503d806000811461021a576040519150601f19603f3d011682016040523d82523d6000602084013e61021f565b606091505b505090505061022f88888f6103df565b61023a8d86866104b7565b915061024788888f6103df565b600180548060200260200160405190810160405280929190818152602001828054801561029357602002820191906000526020600020905b81548152602001906001019080831161027f575b505050505090509b509b9950505050505050505050565b60005a9050600173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff861614610377576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528616906370a0823190602401602060405180830381865afa15801561034e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037291906108ac565b610390565b8373ffffffffffffffffffffffffffffffffffffffff16315b8154600181018355600092835260209092209091015581156103d9575a6103b790826108f4565b6103c39061116c61090d565b6000808282546103d3919061090d565b90915550505b50505050565b60005b828110156103d95730633bbb2e1d85858481811061040257610402610920565b9050602002016020810190610417919061094f565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9182166004820152908516602482015260006044820152606401600060405180830381600087803b15801561048c57600080fd5b505af11580156104a0573d6000803e3d6000fd5b5050505080806104af9061096c565b9150506103e2565b6000805a905061051484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505073ffffffffffffffffffffffffffffffffffffffff891692915050610536565b506000545a61052390836108f4565b61052d91906108f4565b95945050505050565b60606105448360008461054b565b9392505050565b606060008473ffffffffffffffffffffffffffffffffffffffff16848460405161057591906109a4565b60006040518083038185875af1925050503d80600081146105b2576040519150601f19603f3d011682016040523d82523d6000602084013e6105b7565b606091505b5092509050806105c957815160208301fd5b509392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146105f357600080fd5b50565b8035610601816105d1565b919050565b60008083601f84011261061857600080fd5b50813567ffffffffffffffff81111561063057600080fd5b6020830191508360208260051b850101111561064b57600080fd5b9250929050565b60008083601f84011261066457600080fd5b50813567ffffffffffffffff81111561067c57600080fd5b60208301915083602082850101111561064b57600080fd5b8035801515811461060157600080fd5b6000604082840312156106b657600080fd5b6040516040810181811067ffffffffffffffff82111715610700577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290508061070f83610694565b8152602083013561071f816105d1565b6020919091015292915050565b60008060008060008060008060008060006101408c8e03121561074e57600080fd5b6107588c356105d1565b8b359a5061076960208d01356105d1565b60208c0135995061077c60408d016105f6565b985060608c0135975061079160808d016105f6565b965067ffffffffffffffff8060a08e013511156107ad57600080fd5b6107bd8e60a08f01358f01610606565b90975095506107ce60c08e016105f6565b94508060e08e013511156107e157600080fd5b506107f28d60e08e01358e01610652565b90935091506108058d6101008e016106a4565b90509295989b509295989b9093969950565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156108585784518352938301939183019160010161083c565b5090979650505050505050565b60008060006060848603121561087a57600080fd5b8335610885816105d1565b92506020840135610895816105d1565b91506108a360408501610694565b90509250925092565b6000602082840312156108be57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610907576109076108c5565b92915050565b80820180821115610907576109076108c5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561096157600080fd5b8135610544816105d1565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361099d5761099d6108c5565b5060010190565b6000825160005b818110156109c557602081860181015185830152016109ab565b50600092019182525091905056fea164736f6c6343000811000a","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c806317b86b161461003b5780633bbb2e1d14610065575b600080fd5b61004e61004936600461072c565b61007a565b60405161005c929190610817565b60405180910390f35b610078610073366004610865565b6102aa565b005b60006060333014610111576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f6f6e6c792073696d756c6174696f6e206c6f67696320697320616c6c6f77656460448201527f20746f2063616c6c202773776170272066756e6374696f6e0000000000000000606482015260840160405180910390fd5b8251156101bf5760208301516040517f66b00f6800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8f811660048301528d81166024830152604482018d90528b811660648301529182166084820152908d16906366b00f689060a401600060405180830381600087803b1580156101a657600080fd5b505af11580156101ba573d6000803e3d6000fd5b505050505b60008673ffffffffffffffffffffffffffffffffffffffff16600060405160006040518083038185875af1925050503d806000811461021a576040519150601f19603f3d011682016040523d82523d6000602084013e61021f565b606091505b505090505061022f88888f6103df565b61023a8d86866104b7565b915061024788888f6103df565b600180548060200260200160405190810160405280929190818152602001828054801561029357602002820191906000526020600020905b81548152602001906001019080831161027f575b505050505090509b509b9950505050505050505050565b60005a9050600173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff861614610377576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528616906370a0823190602401602060405180830381865afa15801561034e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037291906108ac565b610390565b8373ffffffffffffffffffffffffffffffffffffffff16315b8154600181018355600092835260209092209091015581156103d9575a6103b790826108f4565b6103c39061116c61090d565b6000808282546103d3919061090d565b90915550505b50505050565b60005b828110156103d95730633bbb2e1d85858481811061040257610402610920565b9050602002016020810190610417919061094f565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9182166004820152908516602482015260006044820152606401600060405180830381600087803b15801561048c57600080fd5b505af11580156104a0573d6000803e3d6000fd5b5050505080806104af9061096c565b9150506103e2565b6000805a905061051484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505073ffffffffffffffffffffffffffffffffffffffff891692915050610536565b506000545a61052390836108f4565b61052d91906108f4565b95945050505050565b60606105448360008461054b565b9392505050565b606060008473ffffffffffffffffffffffffffffffffffffffff16848460405161057591906109a4565b60006040518083038185875af1925050503d80600081146105b2576040519150601f19603f3d011682016040523d82523d6000602084013e6105b7565b606091505b5092509050806105c957815160208301fd5b509392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146105f357600080fd5b50565b8035610601816105d1565b919050565b60008083601f84011261061857600080fd5b50813567ffffffffffffffff81111561063057600080fd5b6020830191508360208260051b850101111561064b57600080fd5b9250929050565b60008083601f84011261066457600080fd5b50813567ffffffffffffffff81111561067c57600080fd5b60208301915083602082850101111561064b57600080fd5b8035801515811461060157600080fd5b6000604082840312156106b657600080fd5b6040516040810181811067ffffffffffffffff82111715610700577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290508061070f83610694565b8152602083013561071f816105d1565b6020919091015292915050565b60008060008060008060008060008060006101408c8e03121561074e57600080fd5b6107588c356105d1565b8b359a5061076960208d01356105d1565b60208c0135995061077c60408d016105f6565b985060608c0135975061079160808d016105f6565b965067ffffffffffffffff8060a08e013511156107ad57600080fd5b6107bd8e60a08f01358f01610606565b90975095506107ce60c08e016105f6565b94508060e08e013511156107e157600080fd5b506107f28d60e08e01358e01610652565b90935091506108058d6101008e016106a4565b90509295989b509295989b9093969950565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156108585784518352938301939183019160010161083c565b5090979650505050505050565b60008060006060848603121561087a57600080fd5b8335610885816105d1565b92506020840135610895816105d1565b91506108a360408501610694565b90509250925092565b6000602082840312156108be57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610907576109076108c5565b92915050565b80820180821115610907576109076108c5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561096157600080fd5b8135610544816105d1565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361099d5761099d6108c5565b5060010190565b6000825160005b818110156109c557602081860181015185830152016109ab565b50600092019182525091905056fea164736f6c6343000811000a","devdoc":{"methods":{}},"userdoc":{"methods":{}}} +{"abi":[{"inputs":[{"internalType":"contract Trader","name":"trader","type":"address"},{"internalType":"contract ISettlement","name":"settlementContract","type":"address"},{"internalType":"address","name":"sellToken","type":"address"},{"internalType":"uint256","name":"sellAmount","type":"uint256"},{"internalType":"address","name":"nativeToken","type":"address"},{"internalType":"address","name":"spardose","type":"address"}],"name":"ensureTradePreconditions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"bool","name":"countGas","type":"bool"}],"name":"storeBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISettlement","name":"settlementContract","type":"address"},{"internalType":"address[]","name":"tokens","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":"0x608060405234801561001057600080fd5b506109a3806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80631d47e7f4146100465780632582edb4146100705780633bbb2e1d14610085575b600080fd5b610059610054366004610696565b610098565b604051610067929190610758565b60405180910390f35b61008361007e3660046107a6565b610215565b005b61008361009336600461081f565b6102f1565b6000606033301461012f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f6f6e6c792073696d756c6174696f6e206c6f67696320697320616c6c6f77656460448201527f20746f2063616c6c202773776170272066756e6374696f6e0000000000000000606482015260840160405180910390fd5b60008573ffffffffffffffffffffffffffffffffffffffff16600060405160006040518083038185875af1925050503d806000811461018a576040519150601f19603f3d011682016040523d82523d6000602084013e61018f565b606091505b505090505061019f87878a610426565b6101aa8885856104fe565b91506101b787878a610426565b600180548060200260200160405190810160405280929190818152602001828054801561020357602002820191906000526020600020905b8154815260200190600101908083116101ef575b50505050509050965096945050505050565b60005a6040517f542eb77d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152878116602483015260448201879052858116606483015284811660848301529192509088169063542eb77d9060a401600060405180830381600087803b1580156102a457600080fd5b505af11580156102b8573d6000803e3d6000fd5b505050505a6102c7908261089e565b6102d39061116c6108b7565b6000808282546102e391906108b7565b909155505050505050505050565b60005a9050600173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff8616146103be576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528616906370a0823190602401602060405180830381865afa158015610395573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103b991906108ca565b6103d7565b8373ffffffffffffffffffffffffffffffffffffffff16315b815460018101835560009283526020909220909101558115610420575a6103fe908261089e565b61040a9061116c6108b7565b60008082825461041a91906108b7565b90915550505b50505050565b60005b828110156104205730633bbb2e1d858584818110610449576104496108e3565b905060200201602081019061045e9190610912565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9182166004820152908516602482015260006044820152606401600060405180830381600087803b1580156104d357600080fd5b505af11580156104e7573d6000803e3d6000fd5b5050505080806104f69061092f565b915050610429565b6000805a905061055b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505073ffffffffffffffffffffffffffffffffffffffff89169291505061057d565b506000545a61056a908361089e565b610574919061089e565b95945050505050565b606061058b83600084610592565b9392505050565b606060008473ffffffffffffffffffffffffffffffffffffffff1684846040516105bc9190610967565b60006040518083038185875af1925050503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b50925090508061061057815160208301fd5b509392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461063a57600080fd5b50565b803561064881610618565b919050565b60008083601f84011261065f57600080fd5b50813567ffffffffffffffff81111561067757600080fd5b60208301915083602082850101111561068f57600080fd5b9250929050565b600080600080600080608087890312156106af57600080fd5b86356106ba81610618565b9550602087013567ffffffffffffffff808211156106d757600080fd5b818901915089601f8301126106eb57600080fd5b8135818111156106fa57600080fd5b8a60208260051b850101111561070f57600080fd5b602083019750955061072360408a0161063d565b9450606089013591508082111561073957600080fd5b5061074689828a0161064d565b979a9699509497509295939492505050565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156107995784518352938301939183019160010161077d565b5090979650505050505050565b60008060008060008060c087890312156107bf57600080fd5b86356107ca81610618565b955060208701356107da81610618565b945060408701356107ea81610618565b935060608701359250608087013561080181610618565b915060a087013561081181610618565b809150509295509295509295565b60008060006060848603121561083457600080fd5b833561083f81610618565b9250602084013561084f81610618565b91506040840135801515811461086457600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156108b1576108b161086f565b92915050565b808201808211156108b1576108b161086f565b6000602082840312156108dc57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561092457600080fd5b813561058b81610618565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109605761096061086f565b5060010190565b6000825160005b81811015610988576020818601810151858301520161096e565b50600092019182525091905056fea164736f6c6343000811000a","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100415760003560e01c80631d47e7f4146100465780632582edb4146100705780633bbb2e1d14610085575b600080fd5b610059610054366004610696565b610098565b604051610067929190610758565b60405180910390f35b61008361007e3660046107a6565b610215565b005b61008361009336600461081f565b6102f1565b6000606033301461012f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f6f6e6c792073696d756c6174696f6e206c6f67696320697320616c6c6f77656460448201527f20746f2063616c6c202773776170272066756e6374696f6e0000000000000000606482015260840160405180910390fd5b60008573ffffffffffffffffffffffffffffffffffffffff16600060405160006040518083038185875af1925050503d806000811461018a576040519150601f19603f3d011682016040523d82523d6000602084013e61018f565b606091505b505090505061019f87878a610426565b6101aa8885856104fe565b91506101b787878a610426565b600180548060200260200160405190810160405280929190818152602001828054801561020357602002820191906000526020600020905b8154815260200190600101908083116101ef575b50505050509050965096945050505050565b60005a6040517f542eb77d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152878116602483015260448201879052858116606483015284811660848301529192509088169063542eb77d9060a401600060405180830381600087803b1580156102a457600080fd5b505af11580156102b8573d6000803e3d6000fd5b505050505a6102c7908261089e565b6102d39061116c6108b7565b6000808282546102e391906108b7565b909155505050505050505050565b60005a9050600173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff8616146103be576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528616906370a0823190602401602060405180830381865afa158015610395573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103b991906108ca565b6103d7565b8373ffffffffffffffffffffffffffffffffffffffff16315b815460018101835560009283526020909220909101558115610420575a6103fe908261089e565b61040a9061116c6108b7565b60008082825461041a91906108b7565b90915550505b50505050565b60005b828110156104205730633bbb2e1d858584818110610449576104496108e3565b905060200201602081019061045e9190610912565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9182166004820152908516602482015260006044820152606401600060405180830381600087803b1580156104d357600080fd5b505af11580156104e7573d6000803e3d6000fd5b5050505080806104f69061092f565b915050610429565b6000805a905061055b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505073ffffffffffffffffffffffffffffffffffffffff89169291505061057d565b506000545a61056a908361089e565b610574919061089e565b95945050505050565b606061058b83600084610592565b9392505050565b606060008473ffffffffffffffffffffffffffffffffffffffff1684846040516105bc9190610967565b60006040518083038185875af1925050503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b50925090508061061057815160208301fd5b509392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461063a57600080fd5b50565b803561064881610618565b919050565b60008083601f84011261065f57600080fd5b50813567ffffffffffffffff81111561067757600080fd5b60208301915083602082850101111561068f57600080fd5b9250929050565b600080600080600080608087890312156106af57600080fd5b86356106ba81610618565b9550602087013567ffffffffffffffff808211156106d757600080fd5b818901915089601f8301126106eb57600080fd5b8135818111156106fa57600080fd5b8a60208260051b850101111561070f57600080fd5b602083019750955061072360408a0161063d565b9450606089013591508082111561073957600080fd5b5061074689828a0161064d565b979a9699509497509295939492505050565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156107995784518352938301939183019160010161077d565b5090979650505050505050565b60008060008060008060c087890312156107bf57600080fd5b86356107ca81610618565b955060208701356107da81610618565b945060408701356107ea81610618565b935060608701359250608087013561080181610618565b915060a087013561081181610618565b809150509295509295509295565b60008060006060848603121561083457600080fd5b833561083f81610618565b9250602084013561084f81610618565b91506040840135801515811461086457600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156108b1576108b161086f565b92915050565b808201808211156108b1576108b161086f565b6000602082840312156108dc57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561092457600080fd5b813561058b81610618565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109605761096061086f565b5060010190565b6000825160005b81811015610988576020818601810151858301520161096e565b50600092019182525091905056fea164736f6c6343000811000a","devdoc":{"methods":{}},"userdoc":{"methods":{}}} diff --git a/crates/contracts/artifacts/Trader.json b/crates/contracts/artifacts/Trader.json index eef29787b2..2884646dee 100644 --- a/crates/contracts/artifacts/Trader.json +++ b/crates/contracts/artifacts/Trader.json @@ -1 +1 @@ -{"abi":[{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"contract ISettlement","name":"settlementContract","type":"address"},{"internalType":"address","name":"sellToken","type":"address"},{"internalType":"uint256","name":"sellAmount","type":"uint256"},{"internalType":"address","name":"nativeToken","type":"address"},{"internalType":"address","name":"spardose","type":"address"}],"name":"prepareSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}],"bytecode":"0x608060405234801561001057600080fd5b50610ba4806100206000396000f3fe60806040526004361061002d5760003560e01c80631626ba7e1461008657806366b00f68146100fe57610034565b3661003457005b600061007c6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525062010000939250506101209050565b9050805160208201f35b34801561009257600080fd5b506100c96100a13660046109cd565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200160405180910390f35b34801561010a57600080fd5b5061011e610119366004610a6e565b6101a2565b005b606060008373ffffffffffffffffffffffffffffffffffffffff16836040516101499190610ad6565b600060405180830381855af49150503d8060008114610184576040519150601f19603f3d011682016040523d82523d6000602084013e610189565b606091505b50925090508061019b57815160208301fd5b5092915050565b6101aa6107c5565b1561023c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f70726570617265537761702063616e206f6e6c792062652063616c6c6564206f60448201527f6e6365000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610385576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa1580156102dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103009190610b05565b9050838110156103835760006103168286610b1e565b9050804710610381578373ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561036757600080fd5b505af115801561037b573d6000803e3d6000fd5b50505050505b505b505b60008473ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e308873ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104139190610b58565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa158015610483573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a79190610b05565b9050838110156105f2576105428673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105239190610b58565b73ffffffffffffffffffffffffffffffffffffffff8716906000610800565b6105f28673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610590573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b49190610b58565b73ffffffffffffffffffffffffffffffffffffffff8716907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610800565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa15801561065f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106839190610b05565b9050848110156107bc5773ffffffffffffffffffffffffffffffffffffffff831663494666b6876106b48489610b1e565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526024820152604401600060405180830381600087803b15801561071f57600080fd5b505af1925050508015610730575060015b6107bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f74726164657220646f6573206e6f74206861766520656e6f7567682073656c6c60448201527f20746f6b656e00000000000000000000000000000000000000000000000000006064820152608401610233565b50505050505050565b6000806107f360017f7f36ecad6e52bbe2ff70badce94360882c890b7877b16131c08eabfc635c9735610b1e565b8054600190915592915050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052906000906108939086168361090b565b905061089e81610920565b610904576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f5361666545524332303a20617070726f76616c206661696c65640000000000006044820152606401610233565b5050505050565b606061091983600084610947565b9392505050565b60008151600014806109415750818060200190518101906109419190610b75565b92915050565b606060008473ffffffffffffffffffffffffffffffffffffffff1684846040516109719190610ad6565b60006040518083038185875af1925050503d80600081146109ae576040519150601f19603f3d011682016040523d82523d6000602084013e6109b3565b606091505b5092509050806109c557815160208301fd5b509392505050565b6000806000604084860312156109e257600080fd5b83359250602084013567ffffffffffffffff80821115610a0157600080fd5b818601915086601f830112610a1557600080fd5b813581811115610a2457600080fd5b876020828501011115610a3657600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114610a6b57600080fd5b50565b600080600080600060a08688031215610a8657600080fd5b8535610a9181610a49565b94506020860135610aa181610a49565b9350604086013592506060860135610ab881610a49565b91506080860135610ac881610a49565b809150509295509295909350565b6000825160005b81811015610af75760208186018101518583015201610add565b506000920191825250919050565b600060208284031215610b1757600080fd5b5051919050565b81810381811115610941577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060208284031215610b6a57600080fd5b815161091981610a49565b600060208284031215610b8757600080fd5b8151801515811461091957600080fdfea164736f6c6343000811000a","deployedBytecode":"0x60806040526004361061002d5760003560e01c80631626ba7e1461008657806366b00f68146100fe57610034565b3661003457005b600061007c6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525062010000939250506101209050565b9050805160208201f35b34801561009257600080fd5b506100c96100a13660046109cd565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200160405180910390f35b34801561010a57600080fd5b5061011e610119366004610a6e565b6101a2565b005b606060008373ffffffffffffffffffffffffffffffffffffffff16836040516101499190610ad6565b600060405180830381855af49150503d8060008114610184576040519150601f19603f3d011682016040523d82523d6000602084013e610189565b606091505b50925090508061019b57815160208301fd5b5092915050565b6101aa6107c5565b1561023c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f70726570617265537761702063616e206f6e6c792062652063616c6c6564206f60448201527f6e6365000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610385576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa1580156102dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103009190610b05565b9050838110156103835760006103168286610b1e565b9050804710610381578373ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561036757600080fd5b505af115801561037b573d6000803e3d6000fd5b50505050505b505b505b60008473ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e308873ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104139190610b58565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa158015610483573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a79190610b05565b9050838110156105f2576105428673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105239190610b58565b73ffffffffffffffffffffffffffffffffffffffff8716906000610800565b6105f28673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610590573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b49190610b58565b73ffffffffffffffffffffffffffffffffffffffff8716907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610800565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa15801561065f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106839190610b05565b9050848110156107bc5773ffffffffffffffffffffffffffffffffffffffff831663494666b6876106b48489610b1e565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526024820152604401600060405180830381600087803b15801561071f57600080fd5b505af1925050508015610730575060015b6107bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f74726164657220646f6573206e6f74206861766520656e6f7567682073656c6c60448201527f20746f6b656e00000000000000000000000000000000000000000000000000006064820152608401610233565b50505050505050565b6000806107f360017f7f36ecad6e52bbe2ff70badce94360882c890b7877b16131c08eabfc635c9735610b1e565b8054600190915592915050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052906000906108939086168361090b565b905061089e81610920565b610904576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f5361666545524332303a20617070726f76616c206661696c65640000000000006044820152606401610233565b5050505050565b606061091983600084610947565b9392505050565b60008151600014806109415750818060200190518101906109419190610b75565b92915050565b606060008473ffffffffffffffffffffffffffffffffffffffff1684846040516109719190610ad6565b60006040518083038185875af1925050503d80600081146109ae576040519150601f19603f3d011682016040523d82523d6000602084013e6109b3565b606091505b5092509050806109c557815160208301fd5b509392505050565b6000806000604084860312156109e257600080fd5b83359250602084013567ffffffffffffffff80821115610a0157600080fd5b818601915086601f830112610a1557600080fd5b813581811115610a2457600080fd5b876020828501011115610a3657600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114610a6b57600080fd5b50565b600080600080600060a08688031215610a8657600080fd5b8535610a9181610a49565b94506020860135610aa181610a49565b9350604086013592506060860135610ab881610a49565b91506080860135610ac881610a49565b809150509295509295909350565b6000825160005b81811015610af75760208186018101518583015201610add565b506000920191825250919050565b600060208284031215610b1757600080fd5b5051919050565b81810381811115610941577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060208284031215610b6a57600080fd5b815161091981610a49565b600060208284031215610b8757600080fd5b8151801515811461091957600080fdfea164736f6c6343000811000a","devdoc":{"methods":{}},"userdoc":{"methods":{}}} +{"abi":[{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"contract ISettlement","name":"settlementContract","type":"address"},{"internalType":"address","name":"sellToken","type":"address"},{"internalType":"uint256","name":"sellAmount","type":"uint256"},{"internalType":"address","name":"nativeToken","type":"address"},{"internalType":"address","name":"spardose","type":"address"}],"name":"ensureTradePreconditions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"stateMutability":"payable","type":"receive"}],"bytecode":"0x608060405234801561001057600080fd5b50610cf4806100206000396000f3fe60806040526004361061002d5760003560e01c80631626ba7e14610086578063542eb77d146100fe57610034565b3661003457005b600061007c6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525062010000939250506101209050565b9050805160208201f35b34801561009257600080fd5b506100c96100a1366004610b10565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200160405180910390f35b34801561010a57600080fd5b5061011e610119366004610bb1565b6101a2565b005b606060008373ffffffffffffffffffffffffffffffffffffffff16836040516101499190610c19565b600060405180830381855af49150503d8060008114610184576040519150601f19603f3d011682016040523d82523d6000602084013e610189565b606091505b50925090508061019b57815160208301fd5b5092915050565b6101aa610ad5565b1561023c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f70726570617265537761702063616e206f6e6c792062652063616c6c6564206f60448201527f6e6365000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610385576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa1580156102dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103009190610c48565b9050838110156103835760006103168286610c61565b9050804710610381578373ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561036757600080fd5b505af115801561037b573d6000803e3d6000fd5b50505050505b505b505b60008473ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e308873ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104139190610ca1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa158015610483573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a79190610c48565b905083811015610902578473ffffffffffffffffffffffffffffffffffffffff1663095ea7b38773ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053c9190610ca1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152600060248201526044016020604051808303816000875af19250505080156105e8575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526105e591810190610cc5565b60015b156105ef57505b8473ffffffffffffffffffffffffffffffffffffffff1663095ea7b38773ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610656573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067a9190610ca1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff90911660048201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248201526044016020604051808303816000875af1925050508015610745575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261074291810190610cc5565b60015b1561074c57505b60008573ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e308973ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107da9190610ca1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa15801561084a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086e9190610c48565b905084811015610900576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f74726164657220646964206e6f7420676976652074686520726571756972656460448201527f20617070726f76616c73000000000000000000000000000000000000000000006064820152608401610233565b505b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa15801561096f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109939190610c48565b905084811015610acc5773ffffffffffffffffffffffffffffffffffffffff831663494666b6876109c48489610c61565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526024820152604401600060405180830381600087803b158015610a2f57600080fd5b505af1925050508015610a40575060015b610acc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f74726164657220646f6573206e6f74206861766520656e6f7567682073656c6c60448201527f20746f6b656e00000000000000000000000000000000000000000000000000006064820152608401610233565b50505050505050565b600080610b0360017f7f36ecad6e52bbe2ff70badce94360882c890b7877b16131c08eabfc635c9735610c61565b8054600190915592915050565b600080600060408486031215610b2557600080fd5b83359250602084013567ffffffffffffffff80821115610b4457600080fd5b818601915086601f830112610b5857600080fd5b813581811115610b6757600080fd5b876020828501011115610b7957600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114610bae57600080fd5b50565b600080600080600060a08688031215610bc957600080fd5b8535610bd481610b8c565b94506020860135610be481610b8c565b9350604086013592506060860135610bfb81610b8c565b91506080860135610c0b81610b8c565b809150509295509295909350565b6000825160005b81811015610c3a5760208186018101518583015201610c20565b506000920191825250919050565b600060208284031215610c5a57600080fd5b5051919050565b81810381811115610c9b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b92915050565b600060208284031215610cb357600080fd5b8151610cbe81610b8c565b9392505050565b600060208284031215610cd757600080fd5b81518015158114610cbe57600080fdfea164736f6c6343000811000a","deployedBytecode":"0x60806040526004361061002d5760003560e01c80631626ba7e14610086578063542eb77d146100fe57610034565b3661003457005b600061007c6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525062010000939250506101209050565b9050805160208201f35b34801561009257600080fd5b506100c96100a1366004610b10565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200160405180910390f35b34801561010a57600080fd5b5061011e610119366004610bb1565b6101a2565b005b606060008373ffffffffffffffffffffffffffffffffffffffff16836040516101499190610c19565b600060405180830381855af49150503d8060008114610184576040519150601f19603f3d011682016040523d82523d6000602084013e610189565b606091505b50925090508061019b57815160208301fd5b5092915050565b6101aa610ad5565b1561023c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f70726570617265537761702063616e206f6e6c792062652063616c6c6564206f60448201527f6e6365000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610385576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa1580156102dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103009190610c48565b9050838110156103835760006103168286610c61565b9050804710610381578373ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561036757600080fd5b505af115801561037b573d6000803e3d6000fd5b50505050505b505b505b60008473ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e308873ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104139190610ca1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa158015610483573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a79190610c48565b905083811015610902578473ffffffffffffffffffffffffffffffffffffffff1663095ea7b38773ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053c9190610ca1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152600060248201526044016020604051808303816000875af19250505080156105e8575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526105e591810190610cc5565b60015b156105ef57505b8473ffffffffffffffffffffffffffffffffffffffff1663095ea7b38773ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610656573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067a9190610ca1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff90911660048201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248201526044016020604051808303816000875af1925050508015610745575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261074291810190610cc5565b60015b1561074c57505b60008573ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e308973ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107da9190610ca1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa15801561084a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086e9190610c48565b905084811015610900576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f74726164657220646964206e6f7420676976652074686520726571756972656460448201527f20617070726f76616c73000000000000000000000000000000000000000000006064820152608401610233565b505b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa15801561096f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109939190610c48565b905084811015610acc5773ffffffffffffffffffffffffffffffffffffffff831663494666b6876109c48489610c61565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526024820152604401600060405180830381600087803b158015610a2f57600080fd5b505af1925050508015610a40575060015b610acc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f74726164657220646f6573206e6f74206861766520656e6f7567682073656c6c60448201527f20746f6b656e00000000000000000000000000000000000000000000000000006064820152608401610233565b50505050505050565b600080610b0360017f7f36ecad6e52bbe2ff70badce94360882c890b7877b16131c08eabfc635c9735610c61565b8054600190915592915050565b600080600060408486031215610b2557600080fd5b83359250602084013567ffffffffffffffff80821115610b4457600080fd5b818601915086601f830112610b5857600080fd5b813581811115610b6757600080fd5b876020828501011115610b7957600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114610bae57600080fd5b50565b600080600080600060a08688031215610bc957600080fd5b8535610bd481610b8c565b94506020860135610be481610b8c565b9350604086013592506060860135610bfb81610b8c565b91506080860135610c0b81610b8c565b809150509295509295909350565b6000825160005b81811015610c3a5760208186018101518583015201610c20565b506000920191825250919050565b600060208284031215610c5a57600080fd5b5051919050565b81810381811115610c9b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b92915050565b600060208284031215610cb357600080fd5b8151610cbe81610b8c565b9392505050565b600060208284031215610cd757600080fd5b81518015158114610cbe57600080fdfea164736f6c6343000811000a","devdoc":{"methods":{}},"userdoc":{"methods":{}}} diff --git a/crates/contracts/solidity/Solver.sol b/crates/contracts/solidity/Solver.sol index cf6aea29ac..f8fd460623 100644 --- a/crates/contracts/solidity/Solver.sol +++ b/crates/contracts/solidity/Solver.sol @@ -17,11 +17,6 @@ contract Solver { using Caller for *; using Math for *; - struct Mock { - bool enabled; - address spardose; - } - uint256 private _simulationOverhead; uint256[] private _queriedBalances; @@ -32,49 +27,23 @@ contract Solver { /// /// @param settlementContract - address of the settlement contract because /// it does not have a stable address in tests. - /// @param trader - address of the order owner doing the trade - /// @param sellToken - address of the token being sold - /// @param sellAmount - amount being sold - /// @param nativeToken - ERC20 version of the chain's token /// @param tokens - list of tokens used in the trade /// @param receiver - address receiving the bought tokens /// @param settlementCall - the calldata of the `settle()` call - /// @param mock - mocking configuration for the simulation; this controls - /// whether things like ETH wrapping, setting allowance and - /// pre-funding should be done on behalf of the user to support - /// quote verification for users who aren't ready to swap. /// /// @return gasUsed - gas used for the `settle()` call /// @return queriedBalances - list of balances stored during the simulation function swap( ISettlement settlementContract, - address payable trader, - address sellToken, - uint256 sellAmount, - address nativeToken, address[] calldata tokens, address payable receiver, - bytes calldata settlementCall, - Mock memory mock + bytes calldata settlementCall ) external returns ( uint256 gasUsed, uint256[] memory queriedBalances ) { require(msg.sender == address(this), "only simulation logic is allowed to call 'swap' function"); - if (mock.enabled) { - // 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, - mock.spardose - ); - } - // Warm the storage for sending ETH to smart contract addresses. // We allow this call to revert becaues it was either unnecessary in the first place // or failing to send `ETH` to the `receiver` will cause a revert in the settlement @@ -135,4 +104,28 @@ contract Solver { address(settlementContract).doCall(settlementCall); gasUsed = gasStart - gasleft() - _simulationOverhead; } + + /// @dev Simple wrapper around `Trader.ensureTradePreconditions()` that + /// discounts the gas used to prepare the swap (setting up approvals + /// and balances) from the total gas cost since that would normally + /// not happen during the settlement. + function ensureTradePreconditions( + Trader trader, + ISettlement settlementContract, + address sellToken, + uint256 sellAmount, + address nativeToken, + address spardose + ) external { + uint256 gasStart = gasleft(); + trader.ensureTradePreconditions( + settlementContract, + sellToken, + sellAmount, + nativeToken, + spardose + ); + // Account for costs of gas used outside of metered section. + _simulationOverhead += gasStart - gasleft() + 4460; + } } diff --git a/crates/contracts/solidity/Trader.sol b/crates/contracts/solidity/Trader.sol index 695bcdd4f1..fb86b5954d 100644 --- a/crates/contracts/solidity/Trader.sol +++ b/crates/contracts/solidity/Trader.sol @@ -70,7 +70,7 @@ contract Trader { /// @param sellAmount - expected amount to be sold according to the quote /// @param nativeToken - ERC20 version of the chain's native token /// @param spardose - piggy bank for requesting additional funds - function prepareSwap( + function ensureTradePreconditions( ISettlement settlementContract, address sellToken, uint256 sellAmount, @@ -104,8 +104,13 @@ contract Trader { // We first reset the allowance to 0 since some ERC20 tokens (e.g. USDT) // require that due to this attack: // https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - IERC20(sellToken).safeApprove(address(settlementContract.vaultRelayer()), 0); - IERC20(sellToken).safeApprove(address(settlementContract.vaultRelayer()), type(uint256).max); + // We catch reverts because we'll later assert the correct approval got set anyway. + try IERC20(sellToken).approve(address(settlementContract.vaultRelayer()), 0) {} + catch {} + try IERC20(sellToken).approve(address(settlementContract.vaultRelayer()), type(uint256).max) {} + catch {} + uint256 allowance = IERC20(sellToken).allowance(address(this), address(settlementContract.vaultRelayer())); + require(allowance >= sellAmount, "trader did not give the required approvals"); } // Ensure that the user has sufficient sell token balance. If not, request some diff --git a/crates/e2e/tests/e2e/quote_verification.rs b/crates/e2e/tests/e2e/quote_verification.rs index 3b50d7ecc3..66ce0eadf9 100644 --- a/crates/e2e/tests/e2e/quote_verification.rs +++ b/crates/e2e/tests/e2e/quote_verification.rs @@ -9,6 +9,7 @@ use { quote::{OrderQuoteRequest, OrderQuoteSide, SellAmount}, }, number::nonzero::U256 as NonZeroU256, + serde_json::json, shared::{ price_estimation::{ trade_verifier::{ @@ -435,4 +436,38 @@ async fn verified_quote_with_simulated_balance(web3: Web3) { .await .unwrap(); assert!(response.verified); + + // Previously quote verification did not set up the trade correctly + // if the user provided pre-interactions. This works now. + let response = services + .submit_quote(&OrderQuoteRequest { + from: H160::zero(), + sell_token: weth.address(), + buy_token: token.address(), + side: OrderQuoteSide::Sell { + sell_amount: SellAmount::BeforeFee { + value: to_wei(1).try_into().unwrap(), + }, + }, + app_data: model::order::OrderCreationAppData::Full { + full: json!({ + "metadata": { + "hooks": { + "pre": [ + { + "target": "0x0000000000000000000000000000000000000000", + "callData": "0x", + "gasLimit": "0" + } + ] + } + } + }) + .to_string(), + }, + ..Default::default() + }) + .await + .unwrap(); + assert!(response.verified); } diff --git a/crates/shared/src/price_estimation/trade_verifier.rs b/crates/shared/src/price_estimation/trade_verifier.rs index 7098695c91..dd99562cb2 100644 --- a/crates/shared/src/price_estimation/trade_verifier.rs +++ b/crates/shared/src/price_estimation/trade_verifier.rs @@ -143,6 +143,7 @@ impl TradeVerifier { out_amount, self.native_token, &self.domain_separator, + self.settlement.address(), )?; let settlement = add_balance_queries(settlement, query, &verification, &solver); @@ -158,28 +159,13 @@ impl TradeVerifier { ) .tx; - let sell_amount = match query.kind { - OrderKind::Sell => query.in_amount.get(), - OrderKind::Buy => *out_amount, - }; - - // Only enable additional mocking (approvals, native token wrapping, - // balance overrides) if the user did not provide pre-interactions. If - // the user did provide pre-interactions, it's reasonable to assume that - // they will set up all the necessary details of the trade. - let mock_enabled = verification.pre_interactions.is_empty(); let simulation = solver .methods() .swap( self.settlement.address(), - verification.from, - query.sell_token, - sell_amount, - self.native_token, tokens.clone(), verification.receiver, Bytes(settlement.data.unwrap().0), - (mock_enabled, Self::SPARDOSE), ) .tx; @@ -471,6 +457,7 @@ fn encode_settlement( out_amount: &U256, native_token: H160, domain_separator: &DomainSeparator, + settlement: H160, ) -> Result { let mut trade_interactions = encode_interactions(&trade.interactions()); if query.buy_token == BUY_ETH_ADDRESS { @@ -483,7 +470,13 @@ fn encode_settlement( OrderKind::Buy => query.in_amount.get(), }; let weth = dummy_contract!(WETH9, native_token); - let calldata = weth.methods().withdraw(buy_amount).tx.data.unwrap().0; + let calldata = weth + .methods() + .withdraw(buy_amount) + .tx + .data + .expect("data gets populated by function call above") + .0; trade_interactions.push((native_token, 0.into(), Bytes(calldata))); tracing::trace!("adding unwrap interaction for paying out ETH"); } @@ -498,11 +491,42 @@ fn encode_settlement( )?); } - let pre_interactions = [ - verification.pre_interactions.clone(), - trade.pre_interactions(), - ] - .concat(); + // Execute interaction to set up trade right before transfering funds. + // This interaction does nothing if the user-provided pre-interactions + // already set everything up (e.g. approvals, balances). That way we can + // correctly verify quotes with or without these user pre-interactions + // with helpful error messages. + let trade_setup_interaction = { + let sell_amount = match query.kind { + OrderKind::Sell => query.in_amount.get(), + OrderKind::Buy => *out_amount, + }; + let solver = dummy_contract!(Solver, trade.solver()); + let setup_call = solver + .ensure_trade_preconditions( + verification.from, + settlement, + query.sell_token, + sell_amount, + native_token, + TradeVerifier::SPARDOSE, + ) + .tx + .data + .expect("data gets populated by function call above") + .0; + Interaction { + target: solver.address(), + value: 0.into(), + data: setup_call, + } + }; + + let user_interactions = verification.pre_interactions.iter().cloned(); + let pre_interactions: Vec<_> = user_interactions + .chain(trade.pre_interactions()) + .chain([trade_setup_interaction]) + .collect(); Ok(EncodedSettlement { tokens: tokens.to_vec(), @@ -668,9 +692,14 @@ fn add_balance_queries( // track how much `sell_token` the `from` address actually spent OrderKind::Buy => (query.sell_token, verification.from), }; - let query_balance = solver.methods().store_balance(token, owner, true); - let query_balance = Bytes(query_balance.tx.data.unwrap().0); - let interaction = (solver.address(), 0.into(), query_balance); + let query_balance_call = solver + .methods() + .store_balance(token, owner, true) + .tx + .data + .expect("data gets populated by function call above") + .0; + let interaction = (solver.address(), 0.into(), Bytes(query_balance_call)); // query balance query at the end of pre-interactions settlement.interactions[0].push(interaction.clone()); // query balance right after we payed out all `buy_token`