From d58ffd7200716c3191930d7debf3bcec089ce693 Mon Sep 17 00:00:00 2001 From: Nicholas Rodrigues Lordello Date: Fri, 6 Dec 2024 12:44:36 +0100 Subject: [PATCH] Enable Auto-detection of Token Balance Overrides (#3149) # Description This PR is a follow up to #3148 and the final PR in the stack. It adds configuration and glue code for enabling the automatic token balance override detection introduced in the aforementioned PR. # Changes - A new `Arguments` type was created for setting balance override configuration and creating the balance overrides instance. - The old implementation of the `BalanceOverriding` trait was superseded by a new one that accepts both a static configuration from the `Arguments` as well as allows optionally for auto-detection - The `Trader` Solidity implementation was changed to only wrap ETH if the trader has sufficient balance. Attempting wrap more than the trader's balance this would cause the simulation to revert without a helpful revert message; and generally means that balance override feature doesn't work for WETH. With the modified implementation, the `Trader.prepareSwap` no longer reverts attempting to wrap more ETH than the balance holds. Now, the `Spardose.requestFunds` will always get called if the `Trader` does not have sufficient `sell_token` balance, and it provides a more helpful message when balance overrides are disabled: ``` 2024-12-04T16:09:19.002Z WARN request{id="2"}:estimator{name="test_quoter"}: shared::price_estimation::trade_verifier: failed verification; returning unverified estimate err=failed to simulate quote Caused by: simulation reverted Some("revert: trader does not have enough sell token") ... ``` ## How to Test An E2E test was modified to include balance override tests for both configured and auto-detected tokens. Additionally, I added a test to ensure that the ETH -> WETH wrapping functionality that previously existed in quote verification simulation did not regress with this change. ## Additional Notes @MartinquaXD commented that the changes to `Trader` did not make much sense. In order to try and address the comment, I moved some code around. In particular, the `Trader` now calls `requestFunds` from the `Spardose` during the `prepareSwap` call (instead of the `Solver` calling `ensureBalance` for the trader when setting up the settlement). IMO this makes a bit more sense conceptually (it is like the trader had a pre-hook that would provide the required funds for the swap). The contract changes are part of this commit: https://github.com/cowprotocol/services/pull/3149/commits/7518ea917a96d98adcf9b3cb7ce618037ae7bc95. ## Configuration The balance overriding feature is **disabled by default**. There are two relevant configuration options that need to be changed in order to enable it: - `QUOTE_TOKEN_BALANCE_OVERRIDES`: a set of `${ADDR}@${SLOT}` configurations for manually enabling token balance overrides for specific tokens (for example, for enabling WETH and USDC on Ethereum Mainnet: `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2@3,0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48@9`). - `QUOTE_AUTODETECT_TOKEN_BALANCE_OVERRIDES`: Set to `true` in order to enable auto-detection of balance override slots. --- crates/contracts/artifacts/Solver.json | 2 +- crates/contracts/artifacts/Spardose.json | 2 +- crates/contracts/artifacts/Swapper.json | 2 +- crates/contracts/artifacts/Trader.json | 2 +- crates/contracts/solidity/Solver.sol | 12 +- crates/contracts/solidity/Spardose.sol | 21 +- crates/contracts/solidity/Trader.sol | 36 ++- .../solidity/libraries/SafeERC20.sol | 13 +- crates/e2e/tests/e2e/quote_verification.rs | 120 +++++++- crates/shared/src/price_estimation/factory.rs | 7 +- crates/shared/src/price_estimation/mod.rs | 22 +- .../src/price_estimation/trade_verifier.rs | 48 ++- .../trade_verifier/balance_overrides.rs | 274 +++++++++++++----- .../balance_overrides/detector.rs | 15 +- 14 files changed, 399 insertions(+), 177 deletions(-) diff --git a/crates/contracts/artifacts/Solver.json b/crates/contracts/artifacts/Solver.json index 0b3ffa8e18..19639cbd96 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":"0x608060405234801561001057600080fd5b50610b26806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806317b86b161461003b5780633bbb2e1d14610065575b600080fd5b61004e610049366004610851565b61007a565b60405161005c92919061093c565b60405180910390f35b61007861007336600461098a565b6103cf565b005b60006060333014610112576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f6f6e6c792073696d756c6174696f6e206c6f67696320697320616c6c6f77656460448201527f20746f2063616c6c202773776170272066756e6374696f6e000000000000000060648201526084015b60405180910390fd5b8251156102e4576040517f57d5a1d300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8e811660048301528c81166024830152604482018c90528a811660648301528d16906357d5a1d390608401600060405180830381600087803b15801561019957600080fd5b505af11580156101ad573d6000803e3d6000fd5b50505060208401516040517fc56cca8300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8f811660048301528e81166024830152604482018e9052909116915063c56cca83906064016020604051808303816000875af1158015610234573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025891906109d5565b6102e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f74726164657220646f6573206e6f74206861766520656e6f7567682073656c6c60448201527f20746f6b656e00000000000000000000000000000000000000000000000000006064820152608401610109565b60008673ffffffffffffffffffffffffffffffffffffffff16600060405160006040518083038185875af1925050503d806000811461033f576040519150601f19603f3d011682016040523d82523d6000602084013e610344565b606091505b505090505061035488888f610504565b61035f8d86866105dc565b915061036c88888f610504565b60018054806020026020016040519081016040528092919081815260200182805480156103b857602002820191906000526020600020905b8154815260200190600101908083116103a4575b505050505090509b509b9950505050505050505050565b60005a9050600173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff86161461049c576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528616906370a0823190602401602060405180830381865afa158015610473573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049791906109f2565b6104b5565b8373ffffffffffffffffffffffffffffffffffffffff16315b8154600181018355600092835260209092209091015581156104fe575a6104dc9082610a3a565b6104e89061116c610a53565b6000808282546104f89190610a53565b90915550505b50505050565b60005b828110156104fe5730633bbb2e1d85858481811061052757610527610a66565b905060200201602081019061053c9190610a95565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9182166004820152908516602482015260006044820152606401600060405180830381600087803b1580156105b157600080fd5b505af11580156105c5573d6000803e3d6000fd5b5050505080806105d490610ab2565b915050610507565b6000805a905061063984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505073ffffffffffffffffffffffffffffffffffffffff89169291505061065b565b506000545a6106489083610a3a565b6106529190610a3a565b95945050505050565b606061066983600084610670565b9392505050565b606060008473ffffffffffffffffffffffffffffffffffffffff16848460405161069a9190610aea565b60006040518083038185875af1925050503d80600081146106d7576040519150601f19603f3d011682016040523d82523d6000602084013e6106dc565b606091505b5092509050806106ee57815160208301fd5b509392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461071857600080fd5b50565b8035610726816106f6565b919050565b60008083601f84011261073d57600080fd5b50813567ffffffffffffffff81111561075557600080fd5b6020830191508360208260051b850101111561077057600080fd5b9250929050565b60008083601f84011261078957600080fd5b50813567ffffffffffffffff8111156107a157600080fd5b60208301915083602082850101111561077057600080fd5b801515811461071857600080fd5b6000604082840312156107d957600080fd5b6040516040810181811067ffffffffffffffff82111715610823577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040529050808235610834816107b9565b81526020830135610844816106f6565b6020919091015292915050565b60008060008060008060008060008060006101408c8e03121561087357600080fd5b61087d8c356106f6565b8b359a5061088e60208d01356106f6565b60208c013599506108a160408d0161071b565b985060608c013597506108b660808d0161071b565b965067ffffffffffffffff8060a08e013511156108d257600080fd5b6108e28e60a08f01358f0161072b565b90975095506108f360c08e0161071b565b94508060e08e0135111561090657600080fd5b506109178d60e08e01358e01610777565b909350915061092a8d6101008e016107c7565b90509295989b509295989b9093969950565b6000604082018483526020604081850152818551808452606086019150828701935060005b8181101561097d57845183529383019391830191600101610961565b5090979650505050505050565b60008060006060848603121561099f57600080fd5b83356109aa816106f6565b925060208401356109ba816106f6565b915060408401356109ca816107b9565b809150509250925092565b6000602082840312156109e757600080fd5b8151610669816107b9565b600060208284031215610a0457600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610a4d57610a4d610a0b565b92915050565b80820180821115610a4d57610a4d610a0b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215610aa757600080fd5b8135610669816106f6565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610ae357610ae3610a0b565b5060010190565b6000825160005b81811015610b0b5760208186018101518583015201610af1565b50600092019182525091905056fea164736f6c6343000811000a","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c806317b86b161461003b5780633bbb2e1d14610065575b600080fd5b61004e610049366004610851565b61007a565b60405161005c92919061093c565b60405180910390f35b61007861007336600461098a565b6103cf565b005b60006060333014610112576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f6f6e6c792073696d756c6174696f6e206c6f67696320697320616c6c6f77656460448201527f20746f2063616c6c202773776170272066756e6374696f6e000000000000000060648201526084015b60405180910390fd5b8251156102e4576040517f57d5a1d300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8e811660048301528c81166024830152604482018c90528a811660648301528d16906357d5a1d390608401600060405180830381600087803b15801561019957600080fd5b505af11580156101ad573d6000803e3d6000fd5b50505060208401516040517fc56cca8300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8f811660048301528e81166024830152604482018e9052909116915063c56cca83906064016020604051808303816000875af1158015610234573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025891906109d5565b6102e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f74726164657220646f6573206e6f74206861766520656e6f7567682073656c6c60448201527f20746f6b656e00000000000000000000000000000000000000000000000000006064820152608401610109565b60008673ffffffffffffffffffffffffffffffffffffffff16600060405160006040518083038185875af1925050503d806000811461033f576040519150601f19603f3d011682016040523d82523d6000602084013e610344565b606091505b505090505061035488888f610504565b61035f8d86866105dc565b915061036c88888f610504565b60018054806020026020016040519081016040528092919081815260200182805480156103b857602002820191906000526020600020905b8154815260200190600101908083116103a4575b505050505090509b509b9950505050505050505050565b60005a9050600173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff86161461049c576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528616906370a0823190602401602060405180830381865afa158015610473573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049791906109f2565b6104b5565b8373ffffffffffffffffffffffffffffffffffffffff16315b8154600181018355600092835260209092209091015581156104fe575a6104dc9082610a3a565b6104e89061116c610a53565b6000808282546104f89190610a53565b90915550505b50505050565b60005b828110156104fe5730633bbb2e1d85858481811061052757610527610a66565b905060200201602081019061053c9190610a95565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9182166004820152908516602482015260006044820152606401600060405180830381600087803b1580156105b157600080fd5b505af11580156105c5573d6000803e3d6000fd5b5050505080806105d490610ab2565b915050610507565b6000805a905061063984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505073ffffffffffffffffffffffffffffffffffffffff89169291505061065b565b506000545a6106489083610a3a565b6106529190610a3a565b95945050505050565b606061066983600084610670565b9392505050565b606060008473ffffffffffffffffffffffffffffffffffffffff16848460405161069a9190610aea565b60006040518083038185875af1925050503d80600081146106d7576040519150601f19603f3d011682016040523d82523d6000602084013e6106dc565b606091505b5092509050806106ee57815160208301fd5b509392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461071857600080fd5b50565b8035610726816106f6565b919050565b60008083601f84011261073d57600080fd5b50813567ffffffffffffffff81111561075557600080fd5b6020830191508360208260051b850101111561077057600080fd5b9250929050565b60008083601f84011261078957600080fd5b50813567ffffffffffffffff8111156107a157600080fd5b60208301915083602082850101111561077057600080fd5b801515811461071857600080fd5b6000604082840312156107d957600080fd5b6040516040810181811067ffffffffffffffff82111715610823577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040529050808235610834816107b9565b81526020830135610844816106f6565b6020919091015292915050565b60008060008060008060008060008060006101408c8e03121561087357600080fd5b61087d8c356106f6565b8b359a5061088e60208d01356106f6565b60208c013599506108a160408d0161071b565b985060608c013597506108b660808d0161071b565b965067ffffffffffffffff8060a08e013511156108d257600080fd5b6108e28e60a08f01358f0161072b565b90975095506108f360c08e0161071b565b94508060e08e0135111561090657600080fd5b506109178d60e08e01358e01610777565b909350915061092a8d6101008e016107c7565b90509295989b509295989b9093969950565b6000604082018483526020604081850152818551808452606086019150828701935060005b8181101561097d57845183529383019391830191600101610961565b5090979650505050505050565b60008060006060848603121561099f57600080fd5b83356109aa816106f6565b925060208401356109ba816106f6565b915060408401356109ca816107b9565b809150509250925092565b6000602082840312156109e757600080fd5b8151610669816107b9565b600060208284031215610a0457600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610a4d57610a4d610a0b565b92915050565b80820180821115610a4d57610a4d610a0b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215610aa757600080fd5b8135610669816106f6565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610ae357610ae3610a0b565b5060010190565b6000825160005b81811015610b0b5760208186018101518583015201610af1565b50600092019182525091905056fea164736f6c6343000811000a","devdoc":{"methods":{}},"userdoc":{"methods":{}}} +{"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":{}}} diff --git a/crates/contracts/artifacts/Spardose.json b/crates/contracts/artifacts/Spardose.json index 08787fb5a7..a801fc11d3 100644 --- a/crates/contracts/artifacts/Spardose.json +++ b/crates/contracts/artifacts/Spardose.json @@ -1 +1 @@ -{"abi":[{"inputs":[{"internalType":"address","name":"trader","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ensureBalance","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"}],"bytecode":"0x608060405234801561001057600080fd5b50610364806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c56cca8314610030575b600080fd5b61004361003e366004610277565b610057565b604051901515815260200160405180910390f35b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015260009182918516906370a0823190602401602060405180830381865afa1580156100c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100ec91906102b3565b90508281106100ff576001915050610133565b600061010b82856102cc565b905061012e73ffffffffffffffffffffffffffffffffffffffff8616878361013a565b925050505b9392505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790529151600092606091908716906101d3908490610306565b6000604051808303816000865af19150503d8060008114610210576040519150601f19603f3d011682016040523d82523d6000602084013e610215565b606091505b50909350905082801561012e575061012e8160008151600014806102485750818060200190518101906102489190610335565b92915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461027257600080fd5b919050565b60008060006060848603121561028c57600080fd5b6102958461024e565b92506102a36020850161024e565b9150604084013590509250925092565b6000602082840312156102c557600080fd5b5051919050565b81810381811115610248577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000825160005b81811015610327576020818601810151858301520161030d565b506000920191825250919050565b60006020828403121561034757600080fd5b8151801515811461013357600080fdfea164736f6c6343000811000a","deployedBytecode":"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c56cca8314610030575b600080fd5b61004361003e366004610277565b610057565b604051901515815260200160405180910390f35b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015260009182918516906370a0823190602401602060405180830381865afa1580156100c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100ec91906102b3565b90508281106100ff576001915050610133565b600061010b82856102cc565b905061012e73ffffffffffffffffffffffffffffffffffffffff8616878361013a565b925050505b9392505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790529151600092606091908716906101d3908490610306565b6000604051808303816000865af19150503d8060008114610210576040519150601f19603f3d011682016040523d82523d6000602084013e610215565b606091505b50909350905082801561012e575061012e8160008151600014806102485750818060200190518101906102489190610335565b92915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461027257600080fd5b919050565b60008060006060848603121561028c57600080fd5b6102958461024e565b92506102a36020850161024e565b9150604084013590509250925092565b6000602082840312156102c557600080fd5b5051919050565b81810381811115610248577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000825160005b81811015610327576020818601810151858301520161030d565b506000920191825250919050565b60006020828403121561034757600080fd5b8151801515811461013357600080fdfea164736f6c6343000811000a","devdoc":{"methods":{}},"userdoc":{"methods":{}}} +{"abi":[{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"requestFunds","outputs":[],"stateMutability":"nonpayable","type":"function"}],"bytecode":"0x608060405234801561001057600080fd5b506102de806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063494666b614610030575b600080fd5b61004361003e36600461023b565b610045565b005b61006673ffffffffffffffffffffffffffffffffffffffff8316338361006a565b5050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052906000906100fd90861683610179565b90506101088161018e565b610172576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f5361666545524332303a207472616e73666572206661696c6564000000000000604482015260640160405180910390fd5b5050505050565b6060610187836000846101b5565b9392505050565b60008151600014806101af5750818060200190518101906101af9190610280565b92915050565b606060008473ffffffffffffffffffffffffffffffffffffffff1684846040516101df91906102a2565b60006040518083038185875af1925050503d806000811461021c576040519150601f19603f3d011682016040523d82523d6000602084013e610221565b606091505b50925090508061023357815160208301fd5b509392505050565b6000806040838503121561024e57600080fd5b823573ffffffffffffffffffffffffffffffffffffffff8116811461027257600080fd5b946020939093013593505050565b60006020828403121561029257600080fd5b8151801515811461018757600080fd5b6000825160005b818110156102c357602081860181015185830152016102a9565b50600092019182525091905056fea164736f6c6343000811000a","deployedBytecode":"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063494666b614610030575b600080fd5b61004361003e36600461023b565b610045565b005b61006673ffffffffffffffffffffffffffffffffffffffff8316338361006a565b5050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052906000906100fd90861683610179565b90506101088161018e565b610172576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f5361666545524332303a207472616e73666572206661696c6564000000000000604482015260640160405180910390fd5b5050505050565b6060610187836000846101b5565b9392505050565b60008151600014806101af5750818060200190518101906101af9190610280565b92915050565b606060008473ffffffffffffffffffffffffffffffffffffffff1684846040516101df91906102a2565b60006040518083038185875af1925050503d806000811461021c576040519150601f19603f3d011682016040523d82523d6000602084013e610221565b606091505b50925090508061023357815160208301fd5b509392505050565b6000806040838503121561024e57600080fd5b823573ffffffffffffffffffffffffffffffffffffffff8116811461027257600080fd5b946020939093013593505050565b60006020828403121561029257600080fd5b8151801515811461018757600080fd5b6000825160005b818110156102c357602081860181015185830152016102a9565b50600092019182525091905056fea164736f6c6343000811000a","devdoc":{"methods":{}},"userdoc":{"methods":{}}} diff --git a/crates/contracts/artifacts/Swapper.json b/crates/contracts/artifacts/Swapper.json index 7f6566ee0d..6efb4a8590 100644 --- a/crates/contracts/artifacts/Swapper.json +++ b/crates/contracts/artifacts/Swapper.json @@ -1 +1 @@ -{"abi":[{"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":"settlement","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Asset","name":"sell","type":"tuple"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Asset","name":"buy","type":"tuple"},{"components":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Allowance","name":"allowance","type":"tuple"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct Interaction","name":"call","type":"tuple"}],"name":"swap","outputs":[{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}],"bytecode":"0x608060405234801561001057600080fd5b506111d5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80631626ba7e1461003b5780639ed280dd146100a7575b600080fd5b610071610049366004610b16565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b6100ba6100b5366004610bcf565b6100c8565b60405190815260200161009e565b6000602085018035906100db9087610c5c565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610147573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016b9190610c79565b1015610179575060006108b8565b6102178673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101eb9190610c92565b60006101fa6020890189610c5c565b73ffffffffffffffffffffffffffffffffffffffff1691906108c1565b61029a8673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610265573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102899190610c92565b602087018035906101fa9089610c5c565b6040805160028082526060820183526000926020830190803683370190505090506102c86020870187610c5c565b816000815181106102db576102db610cde565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015261030b90860186610c5c565b8160018151811061031e5761031e610cde565b73ffffffffffffffffffffffffffffffffffffffff92909216602092830291909101820152604080516002808252606082018352600093919290918301908036833701905050905085602001358160008151811061037e5761037e610cde565b6020026020010181815250508660200135816001815181106103a2576103a2610cde565b6020908102919091010152604080516001808252818301909252600091816020015b6104406040518061016001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600063ffffffff16815260200160008019168152602001600081526020016000815260200160008152602001606081525090565b8152602001906001900390816103c45790505090506040518061016001604052806000815260200160018152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001896020013581526020018860200135815260200163ffffffff801681526020016000801b815260200160008152602001604081526020016000815260200130604051602001610506919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528152508160008151811061052b5761052b610cde565b602002602001018190525061053e610aef565b60208088013590610551908b018b610c5c565b73ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e8c61057a60208c018c610c5c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa1580156105ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060e9190610c79565b101561078c5760408051600180825281830190925290816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610629575050815261066660208a018a610c5c565b8151805160009061067957610679610cde565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9092169091526106ac908a018a610c5c565b73ffffffffffffffffffffffffffffffffffffffff1663095ea7b36106d460208a018a610c5c565b60405173ffffffffffffffffffffffffffffffffffffffff909116602482015260208a01356044820152606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b929092179091529050816000602002015160008151811061077c5761077c610cde565b6020026020010151604001819052505b60408051600180825281830190925290816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816107a157505060208201526107dd86610d85565b602082015180516000906107f3576107f3610cde565b60200260200101819052506108b18a73ffffffffffffffffffffffffffffffffffffffff166313d79a0b868686866040516024016108349493929190611084565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b9290921790915273ffffffffffffffffffffffffffffffffffffffff8d16915061099c565b9450505050505b95945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905290600090610954908616836109b1565b9050610995816040518060400160405280601a81526020017f5361666545524332303a20617070726f76616c206661696c65640000000000008152506109bf565b5050505050565b60006109aa83600084610a0f565b9392505050565b60606109aa83600084610a42565b6109c882610ac8565b8190610a0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a01919061113d565b60405180910390fd5b505050565b60005a905060008083516020850186885af1610a2f573d6000803e3d6000fd5b5a610a3a9082611150565b949350505050565b606060008473ffffffffffffffffffffffffffffffffffffffff168484604051610a6c919061118a565b60006040518083038185875af1925050503d8060008114610aa9576040519150601f19603f3d011682016040523d82523d6000602084013e610aae565b606091505b509250905080610ac057815160208301fd5b509392505050565b6000815160001480610ae9575081806020019051810190610ae991906111a6565b92915050565b60405180606001604052806003905b6060815260200190600190039081610afe5790505090565b600080600060408486031215610b2b57600080fd5b83359250602084013567ffffffffffffffff80821115610b4a57600080fd5b818601915086601f830112610b5e57600080fd5b813581811115610b6d57600080fd5b876020828501011115610b7f57600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114610bb457600080fd5b50565b600060408284031215610bc957600080fd5b50919050565b60008060008060006101008688031215610be857600080fd5b8535610bf381610b92565b9450610c028760208801610bb7565b9350610c118760608801610bb7565b9250610c208760a08801610bb7565b915060e086013567ffffffffffffffff811115610c3c57600080fd5b860160608189031215610c4e57600080fd5b809150509295509295909350565b600060208284031215610c6e57600080fd5b81356109aa81610b92565b600060208284031215610c8b57600080fd5b5051919050565b600060208284031215610ca457600080fd5b81516109aa81610b92565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040516060810167ffffffffffffffff81118282101715610d3057610d30610caf565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610d7d57610d7d610caf565b604052919050565b600060608236031215610d9757600080fd5b610d9f610d0d565b8235610daa81610b92565b815260208381013581830152604084013567ffffffffffffffff80821115610dd157600080fd5b9085019036601f830112610de457600080fd5b813581811115610df657610df6610caf565b610e26847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610d36565b91508082523684828501011115610e3c57600080fd5b808484018584013760009082019093019290925250604082015292915050565b60005b83811015610e77578181015183820152602001610e5f565b50506000910152565b60008151808452610e98816020860160208601610e5c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015610faa5782840389528151610160815186528682015187870152604080830151610f2d8289018273ffffffffffffffffffffffffffffffffffffffff169052565b5050606082810151908701526080808301519087015260a08083015163ffffffff169087015260c0808301519087015260e080830151908701526101008083015190870152610120808301519087015261014091820151918601819052610f9681870183610e80565b9a87019a9550505090840190600101610ee8565b5091979650505050505050565b6000826060808201846000805b6003811015610faa578584038952825180518086526020918201918087019190600582901b88018101865b8381101561106d578982037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00185528551805173ffffffffffffffffffffffffffffffffffffffff16835283810151848401526040908101519083018c905261105a8c840182610e80565b9684019695840195925050600101610fef565b509c81019c97509590950194505050600101610fc4565b6080808252855190820181905260009060209060a0840190828901845b828110156110d357815173ffffffffffffffffffffffffffffffffffffffff16845292840192908401906001016110a1565b5050508381038285015286518082528783019183019060005b81811015611108578351835292840192918401916001016110ec565b5050848103604086015261111c8188610eca565b9250505082810360608401526111328185610fb7565b979650505050505050565b6020815260006109aa6020830184610e80565b81810381811115610ae9577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000825161119c818460208701610e5c565b9190910192915050565b6000602082840312156111b857600080fd5b815180151581146109aa57600080fdfea164736f6c6343000811000a","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c80631626ba7e1461003b5780639ed280dd146100a7575b600080fd5b610071610049366004610b16565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b6100ba6100b5366004610bcf565b6100c8565b60405190815260200161009e565b6000602085018035906100db9087610c5c565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610147573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016b9190610c79565b1015610179575060006108b8565b6102178673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101eb9190610c92565b60006101fa6020890189610c5c565b73ffffffffffffffffffffffffffffffffffffffff1691906108c1565b61029a8673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610265573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102899190610c92565b602087018035906101fa9089610c5c565b6040805160028082526060820183526000926020830190803683370190505090506102c86020870187610c5c565b816000815181106102db576102db610cde565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015261030b90860186610c5c565b8160018151811061031e5761031e610cde565b73ffffffffffffffffffffffffffffffffffffffff92909216602092830291909101820152604080516002808252606082018352600093919290918301908036833701905050905085602001358160008151811061037e5761037e610cde565b6020026020010181815250508660200135816001815181106103a2576103a2610cde565b6020908102919091010152604080516001808252818301909252600091816020015b6104406040518061016001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600063ffffffff16815260200160008019168152602001600081526020016000815260200160008152602001606081525090565b8152602001906001900390816103c45790505090506040518061016001604052806000815260200160018152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001896020013581526020018860200135815260200163ffffffff801681526020016000801b815260200160008152602001604081526020016000815260200130604051602001610506919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528152508160008151811061052b5761052b610cde565b602002602001018190525061053e610aef565b60208088013590610551908b018b610c5c565b73ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e8c61057a60208c018c610c5c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa1580156105ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060e9190610c79565b101561078c5760408051600180825281830190925290816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610629575050815261066660208a018a610c5c565b8151805160009061067957610679610cde565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9092169091526106ac908a018a610c5c565b73ffffffffffffffffffffffffffffffffffffffff1663095ea7b36106d460208a018a610c5c565b60405173ffffffffffffffffffffffffffffffffffffffff909116602482015260208a01356044820152606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b929092179091529050816000602002015160008151811061077c5761077c610cde565b6020026020010151604001819052505b60408051600180825281830190925290816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816107a157505060208201526107dd86610d85565b602082015180516000906107f3576107f3610cde565b60200260200101819052506108b18a73ffffffffffffffffffffffffffffffffffffffff166313d79a0b868686866040516024016108349493929190611084565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b9290921790915273ffffffffffffffffffffffffffffffffffffffff8d16915061099c565b9450505050505b95945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905290600090610954908616836109b1565b9050610995816040518060400160405280601a81526020017f5361666545524332303a20617070726f76616c206661696c65640000000000008152506109bf565b5050505050565b60006109aa83600084610a0f565b9392505050565b60606109aa83600084610a42565b6109c882610ac8565b8190610a0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a01919061113d565b60405180910390fd5b505050565b60005a905060008083516020850186885af1610a2f573d6000803e3d6000fd5b5a610a3a9082611150565b949350505050565b606060008473ffffffffffffffffffffffffffffffffffffffff168484604051610a6c919061118a565b60006040518083038185875af1925050503d8060008114610aa9576040519150601f19603f3d011682016040523d82523d6000602084013e610aae565b606091505b509250905080610ac057815160208301fd5b509392505050565b6000815160001480610ae9575081806020019051810190610ae991906111a6565b92915050565b60405180606001604052806003905b6060815260200190600190039081610afe5790505090565b600080600060408486031215610b2b57600080fd5b83359250602084013567ffffffffffffffff80821115610b4a57600080fd5b818601915086601f830112610b5e57600080fd5b813581811115610b6d57600080fd5b876020828501011115610b7f57600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114610bb457600080fd5b50565b600060408284031215610bc957600080fd5b50919050565b60008060008060006101008688031215610be857600080fd5b8535610bf381610b92565b9450610c028760208801610bb7565b9350610c118760608801610bb7565b9250610c208760a08801610bb7565b915060e086013567ffffffffffffffff811115610c3c57600080fd5b860160608189031215610c4e57600080fd5b809150509295509295909350565b600060208284031215610c6e57600080fd5b81356109aa81610b92565b600060208284031215610c8b57600080fd5b5051919050565b600060208284031215610ca457600080fd5b81516109aa81610b92565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040516060810167ffffffffffffffff81118282101715610d3057610d30610caf565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610d7d57610d7d610caf565b604052919050565b600060608236031215610d9757600080fd5b610d9f610d0d565b8235610daa81610b92565b815260208381013581830152604084013567ffffffffffffffff80821115610dd157600080fd5b9085019036601f830112610de457600080fd5b813581811115610df657610df6610caf565b610e26847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610d36565b91508082523684828501011115610e3c57600080fd5b808484018584013760009082019093019290925250604082015292915050565b60005b83811015610e77578181015183820152602001610e5f565b50506000910152565b60008151808452610e98816020860160208601610e5c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015610faa5782840389528151610160815186528682015187870152604080830151610f2d8289018273ffffffffffffffffffffffffffffffffffffffff169052565b5050606082810151908701526080808301519087015260a08083015163ffffffff169087015260c0808301519087015260e080830151908701526101008083015190870152610120808301519087015261014091820151918601819052610f9681870183610e80565b9a87019a9550505090840190600101610ee8565b5091979650505050505050565b6000826060808201846000805b6003811015610faa578584038952825180518086526020918201918087019190600582901b88018101865b8381101561106d578982037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00185528551805173ffffffffffffffffffffffffffffffffffffffff16835283810151848401526040908101519083018c905261105a8c840182610e80565b9684019695840195925050600101610fef565b509c81019c97509590950194505050600101610fc4565b6080808252855190820181905260009060209060a0840190828901845b828110156110d357815173ffffffffffffffffffffffffffffffffffffffff16845292840192908401906001016110a1565b5050508381038285015286518082528783019183019060005b81811015611108578351835292840192918401916001016110ec565b5050848103604086015261111c8188610eca565b9250505082810360608401526111328185610fb7565b979650505050505050565b6020815260006109aa6020830184610e80565b81810381811115610ae9577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000825161119c818460208701610e5c565b9190910192915050565b6000602082840312156111b857600080fd5b815180151581146109aa57600080fdfea164736f6c6343000811000a","devdoc":{"methods":{}},"userdoc":{"methods":{}}} +{"abi":[{"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":"settlement","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Asset","name":"sell","type":"tuple"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Asset","name":"buy","type":"tuple"},{"components":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Allowance","name":"allowance","type":"tuple"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct Interaction","name":"call","type":"tuple"}],"name":"swap","outputs":[{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}],"bytecode":"0x608060405234801561001057600080fd5b506111a6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80631626ba7e1461003b5780639ed280dd146100a7575b600080fd5b610071610049366004610afa565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b6100ba6100b5366004610bb3565b6100c8565b60405190815260200161009e565b6000602085018035906100db9087610c40565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610147573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016b9190610c5d565b1015610179575060006108b8565b6102178673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101eb9190610c76565b60006101fa6020890189610c40565b73ffffffffffffffffffffffffffffffffffffffff1691906108c1565b61029a8673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610265573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102899190610c76565b602087018035906101fa9089610c40565b6040805160028082526060820183526000926020830190803683370190505090506102c86020870187610c40565b816000815181106102db576102db610cc2565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015261030b90860186610c40565b8160018151811061031e5761031e610cc2565b73ffffffffffffffffffffffffffffffffffffffff92909216602092830291909101820152604080516002808252606082018352600093919290918301908036833701905050905085602001358160008151811061037e5761037e610cc2565b6020026020010181815250508660200135816001815181106103a2576103a2610cc2565b6020908102919091010152604080516001808252818301909252600091816020015b6104406040518061016001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600063ffffffff16815260200160008019168152602001600081526020016000815260200160008152602001606081525090565b8152602001906001900390816103c45790505090506040518061016001604052806000815260200160018152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001896020013581526020018860200135815260200163ffffffff801681526020016000801b815260200160008152602001604081526020016000815260200130604051602001610506919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528152508160008151811061052b5761052b610cc2565b602002602001018190525061053e610ad3565b60208088013590610551908b018b610c40565b73ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e8c61057a60208c018c610c40565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa1580156105ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060e9190610c5d565b101561078c5760408051600180825281830190925290816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610629575050815261066660208a018a610c40565b8151805160009061067957610679610cc2565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9092169091526106ac908a018a610c40565b73ffffffffffffffffffffffffffffffffffffffff1663095ea7b36106d460208a018a610c40565b60405173ffffffffffffffffffffffffffffffffffffffff909116602482015260208a01356044820152606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b929092179091529050816000602002015160008151811061077c5761077c610cc2565b6020026020010151604001819052505b60408051600180825281830190925290816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816107a157505060208201526107dd86610d69565b602082015180516000906107f3576107f3610cc2565b60200260200101819052506108b18a73ffffffffffffffffffffffffffffffffffffffff166313d79a0b868686866040516024016108349493929190611068565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b9290921790915273ffffffffffffffffffffffffffffffffffffffff8d1691506109d0565b9450505050505b95945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905290600090610954908616836109e5565b905061095f816109f3565b6109c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f5361666545524332303a20617070726f76616c206661696c6564000000000000604482015260640160405180910390fd5b5050505050565b60006109de83600084610a1a565b9392505050565b60606109de83600084610a4d565b6000815160001480610a14575081806020019051810190610a149190611121565b92915050565b60005a905060008083516020850186885af1610a3a573d6000803e3d6000fd5b5a610a459082611143565b949350505050565b606060008473ffffffffffffffffffffffffffffffffffffffff168484604051610a77919061117d565b60006040518083038185875af1925050503d8060008114610ab4576040519150601f19603f3d011682016040523d82523d6000602084013e610ab9565b606091505b509250905080610acb57815160208301fd5b509392505050565b60405180606001604052806003905b6060815260200190600190039081610ae25790505090565b600080600060408486031215610b0f57600080fd5b83359250602084013567ffffffffffffffff80821115610b2e57600080fd5b818601915086601f830112610b4257600080fd5b813581811115610b5157600080fd5b876020828501011115610b6357600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114610b9857600080fd5b50565b600060408284031215610bad57600080fd5b50919050565b60008060008060006101008688031215610bcc57600080fd5b8535610bd781610b76565b9450610be68760208801610b9b565b9350610bf58760608801610b9b565b9250610c048760a08801610b9b565b915060e086013567ffffffffffffffff811115610c2057600080fd5b860160608189031215610c3257600080fd5b809150509295509295909350565b600060208284031215610c5257600080fd5b81356109de81610b76565b600060208284031215610c6f57600080fd5b5051919050565b600060208284031215610c8857600080fd5b81516109de81610b76565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040516060810167ffffffffffffffff81118282101715610d1457610d14610c93565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610d6157610d61610c93565b604052919050565b600060608236031215610d7b57600080fd5b610d83610cf1565b8235610d8e81610b76565b815260208381013581830152604084013567ffffffffffffffff80821115610db557600080fd5b9085019036601f830112610dc857600080fd5b813581811115610dda57610dda610c93565b610e0a847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610d1a565b91508082523684828501011115610e2057600080fd5b808484018584013760009082019093019290925250604082015292915050565b60005b83811015610e5b578181015183820152602001610e43565b50506000910152565b60008151808452610e7c816020860160208601610e40565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015610f8e5782840389528151610160815186528682015187870152604080830151610f118289018273ffffffffffffffffffffffffffffffffffffffff169052565b5050606082810151908701526080808301519087015260a08083015163ffffffff169087015260c0808301519087015260e080830151908701526101008083015190870152610120808301519087015261014091820151918601819052610f7a81870183610e64565b9a87019a9550505090840190600101610ecc565b5091979650505050505050565b6000826060808201846000805b6003811015610f8e578584038952825180518086526020918201918087019190600582901b88018101865b83811015611051578982037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00185528551805173ffffffffffffffffffffffffffffffffffffffff16835283810151848401526040908101519083018c905261103e8c840182610e64565b9684019695840195925050600101610fd3565b509c81019c97509590950194505050600101610fa8565b6080808252855190820181905260009060209060a0840190828901845b828110156110b757815173ffffffffffffffffffffffffffffffffffffffff1684529284019290840190600101611085565b5050508381038285015286518082528783019183019060005b818110156110ec578351835292840192918401916001016110d0565b505084810360408601526111008188610eae565b9250505082810360608401526111168185610f9b565b979650505050505050565b60006020828403121561113357600080fd5b815180151581146109de57600080fd5b81810381811115610a14577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000825161118f818460208701610e40565b919091019291505056fea164736f6c6343000811000a","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c80631626ba7e1461003b5780639ed280dd146100a7575b600080fd5b610071610049366004610afa565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b6100ba6100b5366004610bb3565b6100c8565b60405190815260200161009e565b6000602085018035906100db9087610c40565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610147573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016b9190610c5d565b1015610179575060006108b8565b6102178673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101eb9190610c76565b60006101fa6020890189610c40565b73ffffffffffffffffffffffffffffffffffffffff1691906108c1565b61029a8673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610265573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102899190610c76565b602087018035906101fa9089610c40565b6040805160028082526060820183526000926020830190803683370190505090506102c86020870187610c40565b816000815181106102db576102db610cc2565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015261030b90860186610c40565b8160018151811061031e5761031e610cc2565b73ffffffffffffffffffffffffffffffffffffffff92909216602092830291909101820152604080516002808252606082018352600093919290918301908036833701905050905085602001358160008151811061037e5761037e610cc2565b6020026020010181815250508660200135816001815181106103a2576103a2610cc2565b6020908102919091010152604080516001808252818301909252600091816020015b6104406040518061016001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600063ffffffff16815260200160008019168152602001600081526020016000815260200160008152602001606081525090565b8152602001906001900390816103c45790505090506040518061016001604052806000815260200160018152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001896020013581526020018860200135815260200163ffffffff801681526020016000801b815260200160008152602001604081526020016000815260200130604051602001610506919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528152508160008151811061052b5761052b610cc2565b602002602001018190525061053e610ad3565b60208088013590610551908b018b610c40565b73ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e8c61057a60208c018c610c40565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa1580156105ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060e9190610c5d565b101561078c5760408051600180825281830190925290816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610629575050815261066660208a018a610c40565b8151805160009061067957610679610cc2565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9092169091526106ac908a018a610c40565b73ffffffffffffffffffffffffffffffffffffffff1663095ea7b36106d460208a018a610c40565b60405173ffffffffffffffffffffffffffffffffffffffff909116602482015260208a01356044820152606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b929092179091529050816000602002015160008151811061077c5761077c610cc2565b6020026020010151604001819052505b60408051600180825281830190925290816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816107a157505060208201526107dd86610d69565b602082015180516000906107f3576107f3610cc2565b60200260200101819052506108b18a73ffffffffffffffffffffffffffffffffffffffff166313d79a0b868686866040516024016108349493929190611068565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b9290921790915273ffffffffffffffffffffffffffffffffffffffff8d1691506109d0565b9450505050505b95945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905290600090610954908616836109e5565b905061095f816109f3565b6109c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f5361666545524332303a20617070726f76616c206661696c6564000000000000604482015260640160405180910390fd5b5050505050565b60006109de83600084610a1a565b9392505050565b60606109de83600084610a4d565b6000815160001480610a14575081806020019051810190610a149190611121565b92915050565b60005a905060008083516020850186885af1610a3a573d6000803e3d6000fd5b5a610a459082611143565b949350505050565b606060008473ffffffffffffffffffffffffffffffffffffffff168484604051610a77919061117d565b60006040518083038185875af1925050503d8060008114610ab4576040519150601f19603f3d011682016040523d82523d6000602084013e610ab9565b606091505b509250905080610acb57815160208301fd5b509392505050565b60405180606001604052806003905b6060815260200190600190039081610ae25790505090565b600080600060408486031215610b0f57600080fd5b83359250602084013567ffffffffffffffff80821115610b2e57600080fd5b818601915086601f830112610b4257600080fd5b813581811115610b5157600080fd5b876020828501011115610b6357600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114610b9857600080fd5b50565b600060408284031215610bad57600080fd5b50919050565b60008060008060006101008688031215610bcc57600080fd5b8535610bd781610b76565b9450610be68760208801610b9b565b9350610bf58760608801610b9b565b9250610c048760a08801610b9b565b915060e086013567ffffffffffffffff811115610c2057600080fd5b860160608189031215610c3257600080fd5b809150509295509295909350565b600060208284031215610c5257600080fd5b81356109de81610b76565b600060208284031215610c6f57600080fd5b5051919050565b600060208284031215610c8857600080fd5b81516109de81610b76565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040516060810167ffffffffffffffff81118282101715610d1457610d14610c93565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610d6157610d61610c93565b604052919050565b600060608236031215610d7b57600080fd5b610d83610cf1565b8235610d8e81610b76565b815260208381013581830152604084013567ffffffffffffffff80821115610db557600080fd5b9085019036601f830112610dc857600080fd5b813581811115610dda57610dda610c93565b610e0a847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610d1a565b91508082523684828501011115610e2057600080fd5b808484018584013760009082019093019290925250604082015292915050565b60005b83811015610e5b578181015183820152602001610e43565b50506000910152565b60008151808452610e7c816020860160208601610e40565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015610f8e5782840389528151610160815186528682015187870152604080830151610f118289018273ffffffffffffffffffffffffffffffffffffffff169052565b5050606082810151908701526080808301519087015260a08083015163ffffffff169087015260c0808301519087015260e080830151908701526101008083015190870152610120808301519087015261014091820151918601819052610f7a81870183610e64565b9a87019a9550505090840190600101610ecc565b5091979650505050505050565b6000826060808201846000805b6003811015610f8e578584038952825180518086526020918201918087019190600582901b88018101865b83811015611051578982037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00185528551805173ffffffffffffffffffffffffffffffffffffffff16835283810151848401526040908101519083018c905261103e8c840182610e64565b9684019695840195925050600101610fd3565b509c81019c97509590950194505050600101610fa8565b6080808252855190820181905260009060209060a0840190828901845b828110156110b757815173ffffffffffffffffffffffffffffffffffffffff1684529284019290840190600101611085565b5050508381038285015286518082528783019183019060005b818110156110ec578351835292840192918401916001016110d0565b505084810360408601526111008188610eae565b9250505082810360608401526111168185610f9b565b979650505050505050565b60006020828403121561113357600080fd5b815180151581146109de57600080fd5b81810381811115610a14577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000825161118f818460208701610e40565b919091019291505056fea164736f6c6343000811000a","devdoc":{"methods":{}},"userdoc":{"methods":{}}} diff --git a/crates/contracts/artifacts/Trader.json b/crates/contracts/artifacts/Trader.json index 2614e657ac..eef29787b2 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"}],"name":"prepareSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}],"bytecode":"0x608060405234801561001057600080fd5b50610a97806100206000396000f3fe60806040526004361061002d5760003560e01c80631626ba7e1461008657806357d5a1d3146100fe57610034565b3661003457005b600061007c6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525062010000939250506101209050565b9050805160208201f35b34801561009257600080fd5b506100c96100a1366004610873565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200160405180910390f35b34801561010a57600080fd5b5061011e610119366004610914565b6101a2565b005b606060008373ffffffffffffffffffffffffffffffffffffffff1683604051610149919061098b565b600060405180830381855af49150503d8060008114610184576040519150601f19603f3d011682016040523d82523d6000602084013e610189565b606091505b50925090508061019b57815160208301fd5b5092915050565b6101aa61065b565b1561023c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f70726570617265537761702063616e206f6e6c792062652063616c6c6564206f60448201527f6e6365000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036103e7576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156102dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061030091906109a7565b9050828110156103e557600061031682856109c0565b905080471015610382576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6e6f7420656e6f7567682045544820746f2077726170000000000000000000006044820152606401610233565b8273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103ca57600080fd5b505af11580156103de573d6000803e3d6000fd5b5050505050505b505b60008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e308773ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610451573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061047591906109fa565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa1580156104e5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050991906109a7565b905082811015610654576105a48573ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610561573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058591906109fa565b73ffffffffffffffffffffffffffffffffffffffff8616906000610696565b6106548573ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061691906109fa565b73ffffffffffffffffffffffffffffffffffffffff8616907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610696565b5050505050565b60008061068960017f7f36ecad6e52bbe2ff70badce94360882c890b7877b16131c08eabfc635c97356109c0565b8054600190915592915050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052906000906107299086168361076a565b9050610654816040518060400160405280601a81526020017f5361666545524332303a20617070726f76616c206661696c656400000000000081525061077f565b6060610778836000846107c6565b9392505050565b6107888261084c565b81906107c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102339190610a17565b505050565b606060008473ffffffffffffffffffffffffffffffffffffffff1684846040516107f0919061098b565b60006040518083038185875af1925050503d806000811461082d576040519150601f19603f3d011682016040523d82523d6000602084013e610832565b606091505b50925090508061084457815160208301fd5b509392505050565b600081516000148061086d57508180602001905181019061086d9190610a68565b92915050565b60008060006040848603121561088857600080fd5b83359250602084013567ffffffffffffffff808211156108a757600080fd5b818601915086601f8301126108bb57600080fd5b8135818111156108ca57600080fd5b8760208285010111156108dc57600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff8116811461091157600080fd5b50565b6000806000806080858703121561092a57600080fd5b8435610935816108ef565b93506020850135610945816108ef565b925060408501359150606085013561095c816108ef565b939692955090935050565b60005b8381101561098257818101518382015260200161096a565b50506000910152565b6000825161099d818460208701610967565b9190910192915050565b6000602082840312156109b957600080fd5b5051919050565b8181038181111561086d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060208284031215610a0c57600080fd5b8151610778816108ef565b6020815260008251806020840152610a36816040850160208701610967565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600060208284031215610a7a57600080fd5b8151801515811461077857600080fdfea164736f6c6343000811000a","deployedBytecode":"0x60806040526004361061002d5760003560e01c80631626ba7e1461008657806357d5a1d3146100fe57610034565b3661003457005b600061007c6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525062010000939250506101209050565b9050805160208201f35b34801561009257600080fd5b506100c96100a1366004610873565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200160405180910390f35b34801561010a57600080fd5b5061011e610119366004610914565b6101a2565b005b606060008373ffffffffffffffffffffffffffffffffffffffff1683604051610149919061098b565b600060405180830381855af49150503d8060008114610184576040519150601f19603f3d011682016040523d82523d6000602084013e610189565b606091505b50925090508061019b57815160208301fd5b5092915050565b6101aa61065b565b1561023c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f70726570617265537761702063616e206f6e6c792062652063616c6c6564206f60448201527f6e6365000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036103e7576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156102dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061030091906109a7565b9050828110156103e557600061031682856109c0565b905080471015610382576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6e6f7420656e6f7567682045544820746f2077726170000000000000000000006044820152606401610233565b8273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103ca57600080fd5b505af11580156103de573d6000803e3d6000fd5b5050505050505b505b60008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e308773ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610451573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061047591906109fa565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa1580156104e5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050991906109a7565b905082811015610654576105a48573ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610561573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058591906109fa565b73ffffffffffffffffffffffffffffffffffffffff8616906000610696565b6106548573ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061691906109fa565b73ffffffffffffffffffffffffffffffffffffffff8616907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610696565b5050505050565b60008061068960017f7f36ecad6e52bbe2ff70badce94360882c890b7877b16131c08eabfc635c97356109c0565b8054600190915592915050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052906000906107299086168361076a565b9050610654816040518060400160405280601a81526020017f5361666545524332303a20617070726f76616c206661696c656400000000000081525061077f565b6060610778836000846107c6565b9392505050565b6107888261084c565b81906107c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102339190610a17565b505050565b606060008473ffffffffffffffffffffffffffffffffffffffff1684846040516107f0919061098b565b60006040518083038185875af1925050503d806000811461082d576040519150601f19603f3d011682016040523d82523d6000602084013e610832565b606091505b50925090508061084457815160208301fd5b509392505050565b600081516000148061086d57508180602001905181019061086d9190610a68565b92915050565b60008060006040848603121561088857600080fd5b83359250602084013567ffffffffffffffff808211156108a757600080fd5b818601915086601f8301126108bb57600080fd5b8135818111156108ca57600080fd5b8760208285010111156108dc57600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff8116811461091157600080fd5b50565b6000806000806080858703121561092a57600080fd5b8435610935816108ef565b93506020850135610945816108ef565b925060408501359150606085013561095c816108ef565b939692955090935050565b60005b8381101561098257818101518382015260200161096a565b50506000910152565b6000825161099d818460208701610967565b9190910192915050565b6000602082840312156109b957600080fd5b5051919050565b8181038181111561086d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060208284031215610a0c57600080fd5b8151610778816108ef565b6020815260008251806020840152610a36816040850160208701610967565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600060208284031215610a7a57600080fd5b8151801515811461077857600080fdfea164736f6c6343000811000a","devdoc":{"methods":{}},"userdoc":{"methods":{}}} +{"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":{}}} diff --git a/crates/contracts/solidity/Solver.sol b/crates/contracts/solidity/Solver.sol index eece404458..cf6aea29ac 100644 --- a/crates/contracts/solidity/Solver.sol +++ b/crates/contracts/solidity/Solver.sol @@ -6,7 +6,6 @@ import { Interaction, Trade, ISettlement } from "./interfaces/ISettlement.sol"; import { Caller } from "./libraries/Caller.sol"; import { Math } from "./libraries/Math.sol"; import { SafeERC20 } from "./libraries/SafeERC20.sol"; -import { Spardose } from "./Spardose.sol"; import { Trader } from "./Trader.sol"; /// @title A contract for impersonating a solver. This contract @@ -71,16 +70,9 @@ contract Solver { settlementContract, sellToken, sellAmount, - nativeToken + nativeToken, + mock.spardose ); - - // Ensure that the user has sufficient sell token balance. In case - // balance overrides are enabled, the Spardose will fund the trader - // with simulated balances. - require( - Spardose(mock.spardose).ensureBalance(trader, sellToken, sellAmount), - "trader does not have enough sell token" - ); } // Warm the storage for sending ETH to smart contract addresses. diff --git a/crates/contracts/solidity/Spardose.sol b/crates/contracts/solidity/Spardose.sol index c1fa6167be..f453a0940e 100644 --- a/crates/contracts/solidity/Spardose.sol +++ b/crates/contracts/solidity/Spardose.sol @@ -12,21 +12,12 @@ import { SafeERC20 } from "./libraries/SafeERC20.sol"; contract Spardose { using SafeERC20 for *; - /// @dev Ensures that the trader has at least `amount` tokens. If not, it - /// will try and transfer the difference to the trader. + /// @dev Request funds from the piggy bank to be transferred to the caller. + /// Reverts if the transfer fails. /// - /// @param trader - the address of the trader - /// @param token - the token to ensure a balance for - /// @param amount - the amount of `token` that the `trader` must hold - /// - /// @return success - the `trader`'s `token` balance is more than `amount` - function ensureBalance(address trader, address token, uint256 amount) external returns (bool success) { - uint256 traderBalance = IERC20(token).balanceOf(trader); - if (traderBalance >= amount) { - return true; - } - - uint256 difference = amount - traderBalance; - return IERC20(token).trySafeTransfer(trader, difference); + /// @param token - the token request funds for + /// @param amount - the amount of `token` to transfer + function requestFunds(address token, uint256 amount) external { + IERC20(token).safeTransfer(msg.sender, amount); } } diff --git a/crates/contracts/solidity/Trader.sol b/crates/contracts/solidity/Trader.sol index c9fa5e0fdf..695bcdd4f1 100644 --- a/crates/contracts/solidity/Trader.sol +++ b/crates/contracts/solidity/Trader.sol @@ -6,6 +6,7 @@ import { Interaction, Trade, ISettlement } from "./interfaces/ISettlement.sol"; import { Caller } from "./libraries/Caller.sol"; import { Math } from "./libraries/Math.sol"; import { SafeERC20 } from "./libraries/SafeERC20.sol"; +import { Spardose } from "./Spardose.sol"; /// @title A contract for impersonating a trader. contract Trader { @@ -62,17 +63,19 @@ contract Trader { receive() external payable {} /// @dev Executes needed actions on behalf of the trader to make the trade possible. - /// (e.g. wrapping ETH and setting approvals) + /// (e.g. wrapping ETH, setting approvals, and funding the account) /// @param settlementContract - pass in settlement contract because it does not have /// a stable address in tests. /// @param sellToken - token being sold by the trade /// @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( ISettlement settlementContract, address sellToken, uint256 sellAmount, - address nativeToken + address nativeToken, + address spardose ) external { require(!alreadyCalled(), "prepareSwap can only be called once"); @@ -80,11 +83,16 @@ contract Trader { uint256 availableNativeToken = IERC20(sellToken).balanceOf(address(this)); if (availableNativeToken < sellAmount) { uint256 amountToWrap = sellAmount - availableNativeToken; - require(address(this).balance >= amountToWrap, "not enough ETH to wrap"); - // Simulate wrapping the missing `ETH` so the user doesn't have to spend gas - // on that just to get a quote. If they are happy with the quote and want to - // create an order they will actually have to do the wrapping, though. - INativeERC20(nativeToken).deposit{value: amountToWrap}(); + // If the user has sufficient balance, simulate the wrapping the missing + // `ETH` so the user doesn't have to spend gas on that just to get a quote. + // If they are happy with the quote and want to create an order they will + // actually have to do the wrapping, though. Note that we don't attempt to + // wrap if the user doesn't have sufficient `ETH` balance, since that would + // revert. Instead, we fall-through so that we handle insufficient sell + // token balances uniformly for all tokens. + if (address(this).balance >= amountToWrap) { + INativeERC20(nativeToken).deposit{value: amountToWrap}(); + } } } @@ -99,6 +107,20 @@ contract Trader { IERC20(sellToken).safeApprove(address(settlementContract.vaultRelayer()), 0); IERC20(sellToken).safeApprove(address(settlementContract.vaultRelayer()), type(uint256).max); } + + // Ensure that the user has sufficient sell token balance. If not, request some + // funds from the Spardose (piggy bank) which will be available if balance + // overrides are enabled. + uint256 sellBalance = IERC20(sellToken).balanceOf(address(this)); + if (sellBalance < sellAmount) { + try Spardose(spardose).requestFunds(sellToken, sellAmount - sellBalance) {} + catch { + // The trader does not have sufficient sell token balance, and the + // piggy bank pre-fund failed, as balance overrides are not available. + // Revert with a helpful message. + revert("trader does not have enough sell token"); + } + } } /// @dev Validate all signature requests. This makes "signing" CoW protocol diff --git a/crates/contracts/solidity/libraries/SafeERC20.sol b/crates/contracts/solidity/libraries/SafeERC20.sol index 9cc30ef35f..1e5e7d708a 100644 --- a/crates/contracts/solidity/libraries/SafeERC20.sol +++ b/crates/contracts/solidity/libraries/SafeERC20.sol @@ -7,24 +7,19 @@ import { Caller } from "./Caller.sol"; library SafeERC20 { using Caller for *; - function trySafeTransfer(IERC20 self, address target, uint256 amount) internal returns (bool success) { + function safeTransfer(IERC20 self, address target, uint256 amount) internal { bytes memory cdata = abi.encodeCall(self.transfer, (target, amount)); - bytes memory rdata; - (success, rdata) = address(self).call(cdata); - return success && check(rdata); + bytes memory rdata = address(self).doCall(cdata); + require(check(rdata), "SafeERC20: transfer failed"); } function safeApprove(IERC20 self, address target, uint256 amount) internal { bytes memory cdata = abi.encodeCall(self.approve, (target, amount)); bytes memory rdata = address(self).doCall(cdata); - ensure(rdata, "SafeERC20: approval failed"); + require(check(rdata), "SafeERC20: approval failed"); } function check(bytes memory rdata) internal pure returns (bool ok) { return rdata.length == 0 || abi.decode(rdata, (bool)); } - - function ensure(bytes memory rdata, string memory message) internal pure { - require(check(rdata), message); - } } diff --git a/crates/e2e/tests/e2e/quote_verification.rs b/crates/e2e/tests/e2e/quote_verification.rs index 2aafb0e98b..8af977edcf 100644 --- a/crates/e2e/tests/e2e/quote_verification.rs +++ b/crates/e2e/tests/e2e/quote_verification.rs @@ -10,7 +10,12 @@ use { number::nonzero::U256 as NonZeroU256, shared::{ price_estimation::{ - trade_verifier::{PriceQuery, TradeVerifier, TradeVerifying}, + trade_verifier::{ + balance_overrides::BalanceOverrides, + PriceQuery, + TradeVerifier, + TradeVerifying, + }, Estimate, Verification, }, @@ -37,6 +42,12 @@ async fn forked_node_bypass_verification_for_rfq_quotes() { .await; } +#[tokio::test] +#[ignore] +async fn local_node_verified_quote_eth_balance() { + run_test(verified_quote_eth_balance).await; +} + #[tokio::test] #[ignore] async fn local_node_verified_quote_for_settlement_contract() { @@ -70,7 +81,7 @@ async fn standard_verified_quote(web3: Web3) { let services = Services::new(&onchain).await; services.start_protocol(solver).await; - // quote where the trader has no balances or approval set. + // quote where the trader has sufficient balance and an approval set. let response = services .submit_quote(&OrderQuoteRequest { from: trader.address(), @@ -110,6 +121,7 @@ async fn test_bypass_verification_for_rfq_quotes(web3: Web3) { web3.clone(), Arc::new(web3.clone()), Arc::new(web3.clone()), + Arc::new(BalanceOverrides::default()), block_stream, onchain.contracts().gp_settlement.address(), onchain.contracts().weth.address(), @@ -182,6 +194,51 @@ async fn test_bypass_verification_for_rfq_quotes(web3: Web3) { ); } +/// Verified quotes work as for WETH trades without wrapping or approvals. +async fn verified_quote_eth_balance(web3: Web3) { + tracing::info!("Setting up chain state."); + let mut onchain = OnchainComponents::deploy(web3).await; + + let [solver] = onchain.make_solvers(to_wei(10)).await; + let [trader] = onchain.make_accounts(to_wei(1)).await; + let [token] = onchain + .deploy_tokens_with_weth_uni_v2_pools(to_wei(1_000), to_wei(1_000)) + .await; + let weth = &onchain.contracts().weth; + + tracing::info!("Starting services."); + let services = Services::new(&onchain).await; + services.start_protocol(solver).await; + + // quote where the trader has no WETH balances or approval set, but + // sufficient ETH for the trade + assert_eq!( + ( + weth.balance_of(trader.address()).call().await.unwrap(), + weth.allowance(trader.address(), onchain.contracts().allowance) + .call() + .await + .unwrap(), + ), + (U256::zero(), U256::zero()), + ); + let response = services + .submit_quote(&OrderQuoteRequest { + from: trader.address(), + sell_token: weth.address(), + buy_token: token.address(), + side: OrderQuoteSide::Sell { + sell_amount: SellAmount::BeforeFee { + value: to_wei(1).try_into().unwrap(), + }, + }, + ..Default::default() + }) + .await + .unwrap(); + assert!(response.verified); +} + /// Test that asserts that we can verify quotes where the settlement contract is /// the trader or receiver. async fn verified_quote_for_settlement_contract(web3: Web3) { @@ -271,30 +328,77 @@ async fn verified_quote_with_simulated_balance(web3: Web3) { let [token] = onchain .deploy_tokens_with_weth_uni_v2_pools(to_wei(1_000), to_wei(1_000)) .await; + let weth = &onchain.contracts().weth; tracing::info!("Starting services."); let services = Services::new(&onchain).await; services .start_protocol_with_args( ExtraServiceArgs { - api: vec![format!( + api: vec![ // The OpenZeppelin `ERC20Mintable` token uses a mapping in // the first (0'th) storage slot for balances. - "--quote-token-balance-overrides={:?}@0", - token.address() - )], + format!("--quote-token-balance-overrides={:?}@0", token.address()), + // We don't configure the WETH token and instead rely on + // auto-detection for balance overrides. + "--quote-autodetect-token-balance-overrides=true".to_string(), + ], ..Default::default() }, solver, ) .await; - // quote where the trader has no balances or approval set. + // quote where the trader has no balances or approval set from TOKEN->WETH + assert_eq!( + ( + token.balance_of(trader.address()).call().await.unwrap(), + token + .allowance(trader.address(), onchain.contracts().allowance) + .call() + .await + .unwrap(), + ), + (U256::zero(), U256::zero()), + ); let response = services .submit_quote(&OrderQuoteRequest { from: trader.address(), sell_token: token.address(), - buy_token: onchain.contracts().weth.address(), + buy_token: weth.address(), + side: OrderQuoteSide::Sell { + sell_amount: SellAmount::BeforeFee { + value: to_wei(1).try_into().unwrap(), + }, + }, + ..Default::default() + }) + .await + .unwrap(); + assert!(response.verified); + + // quote where the trader has no balances or approval set from WETH->TOKEN + assert_eq!( + ( + onchain + .web3() + .eth() + .balance(trader.address(), None) + .await + .unwrap(), + weth.balance_of(trader.address()).call().await.unwrap(), + weth.allowance(trader.address(), onchain.contracts().allowance) + .call() + .await + .unwrap(), + ), + (U256::zero(), U256::zero(), U256::zero()), + ); + let response = services + .submit_quote(&OrderQuoteRequest { + from: trader.address(), + sell_token: weth.address(), + buy_token: token.address(), side: OrderQuoteSide::Sell { sell_amount: SellAmount::BeforeFee { value: to_wei(1).try_into().unwrap(), diff --git a/crates/shared/src/price_estimation/factory.rs b/crates/shared/src/price_estimation/factory.rs index 2d660adf03..b23f23385a 100644 --- a/crates/shared/src/price_estimation/factory.rs +++ b/crates/shared/src/price_estimation/factory.rs @@ -113,20 +113,19 @@ impl<'a> PriceEstimatorFactory<'a> { None => Arc::new(web3.clone()), }; - let balance_overrides = Arc::new(args.quote_token_balance_overrides.clone()); + let balance_overrides = args.balance_overrides.init(simulator.clone()); let verifier = TradeVerifier::new( web3, simulator, components.code_fetcher.clone(), + balance_overrides, network.block_stream.clone(), network.settlement, network.native_token, args.quote_inaccuracy_limit.clone(), ) - .await? - .with_balance_overrides(balance_overrides); - + .await?; Ok(Some(Arc::new(verifier))) } diff --git a/crates/shared/src/price_estimation/mod.rs b/crates/shared/src/price_estimation/mod.rs index 607925bc83..5db9810d01 100644 --- a/crates/shared/src/price_estimation/mod.rs +++ b/crates/shared/src/price_estimation/mod.rs @@ -1,5 +1,5 @@ use { - self::trade_verifier::balance_overrides::ConfigurationBalanceOverrides, + self::trade_verifier::balance_overrides, crate::{ arguments::{display_option, display_secret_option, ExternalSolver}, trade_finding::Interaction, @@ -213,16 +213,8 @@ pub struct Arguments { )] pub quote_timeout: Duration, - /// Token configuration for simulated balances on verified quotes. This - /// allows the quote verification system to produce verified quotes for - /// traders without sufficient balance for the configured token pairs. - /// - /// The expected format is a comma separated list of `${ADDR}@${SLOT}`, - /// where `ADDR` is the token address and `SLOT` is the Solidity storage - /// slot for the balances mapping. For example for WETH: - /// `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2@3`. - #[clap(long, env, default_value_t)] - pub quote_token_balance_overrides: ConfigurationBalanceOverrides, + #[clap(flatten)] + pub balance_overrides: balance_overrides::Arguments, } #[derive(clap::Parser)] @@ -302,7 +294,7 @@ impl Display for Arguments { quote_inaccuracy_limit, quote_verification, quote_timeout, - quote_token_balance_overrides, + balance_overrides, } = self; display_option( @@ -380,11 +372,7 @@ impl Display for Arguments { writeln!(f, "quote_inaccuracy_limit: {}", quote_inaccuracy_limit)?; writeln!(f, "quote_verification: {:?}", quote_verification)?; writeln!(f, "quote_timeout: {:?}", quote_timeout)?; - writeln!( - f, - "quote_token_balance_overrides: {:?}", - quote_token_balance_overrides - )?; + write!(f, "{}", balance_overrides)?; Ok(()) } diff --git a/crates/shared/src/price_estimation/trade_verifier.rs b/crates/shared/src/price_estimation/trade_verifier.rs index fed26bb928..8d871f4656 100644 --- a/crates/shared/src/price_estimation/trade_verifier.rs +++ b/crates/shared/src/price_estimation/trade_verifier.rs @@ -1,11 +1,7 @@ pub mod balance_overrides; use { - self::balance_overrides::{ - BalanceOverrideRequest, - BalanceOverriding, - ConfigurationBalanceOverrides, - }, + self::balance_overrides::{BalanceOverrideRequest, BalanceOverriding}, super::{Estimate, Verification}, crate::{ code_fetching::CodeFetching, @@ -76,10 +72,12 @@ impl TradeVerifier { const SPARDOSE: H160 = addr!("0000000000000000000000000000000000020000"); const TRADER_IMPL: H160 = addr!("0000000000000000000000000000000000010000"); + #[allow(clippy::too_many_arguments)] pub async fn new( web3: Web3, simulator: Arc, code_fetcher: Arc, + balance_overrides: Arc, block_stream: CurrentBlockWatcher, settlement: H160, native_token: H160, @@ -91,7 +89,7 @@ impl TradeVerifier { Ok(Self { simulator, code_fetcher, - balance_overrides: Arc::new(ConfigurationBalanceOverrides::default()), + balance_overrides, block_stream, settlement: settlement_contract, native_token, @@ -101,11 +99,6 @@ impl TradeVerifier { }) } - pub fn with_balance_overrides(mut self, balance_overrides: Arc) -> Self { - self.balance_overrides = balance_overrides; - self - } - async fn verify_inner( &self, query: &PriceQuery, @@ -344,23 +337,24 @@ impl TradeVerifier { // not alter solver balances which may be used during settlement. We use // a similar strategy for determining whether or not to set approvals on // behalf of the trader. - if let Some(solver_balance_override) = - self.balance_overrides - .state_override(&BalanceOverrideRequest { - token: query.sell_token, - holder: Self::SPARDOSE, - amount: match query.kind { - OrderKind::Sell => query.in_amount.get(), - OrderKind::Buy => trade.out_amount( - &query.buy_token, - &query.sell_token, - &query.in_amount.get(), - &query.kind, - )?, - }, - }) + if let Some(solver_balance_override) = self + .balance_overrides + .state_override(BalanceOverrideRequest { + token: query.sell_token, + holder: Self::SPARDOSE, + amount: match query.kind { + OrderKind::Sell => query.in_amount.get(), + OrderKind::Buy => trade.out_amount( + &query.buy_token, + &query.sell_token, + &query.in_amount.get(), + &query.kind, + )?, + }, + }) + .await { - tracing::debug!(?solver_balance_override, "solver balance override enabled"); + tracing::trace!(?solver_balance_override, "solver balance override enabled"); overrides.insert(query.sell_token, solver_balance_override); } diff --git a/crates/shared/src/price_estimation/trade_verifier/balance_overrides.rs b/crates/shared/src/price_estimation/trade_verifier/balance_overrides.rs index ae7550f9a2..d1f85c03d3 100644 --- a/crates/shared/src/price_estimation/trade_verifier/balance_overrides.rs +++ b/crates/shared/src/price_estimation/trade_verifier/balance_overrides.rs @@ -1,7 +1,10 @@ mod detector; use { + self::detector::{DetectionError, Detector}, + crate::code_simulation::CodeSimulating, anyhow::Context as _, + cached::{Cached, SizedCache}, ethcontract::{Address, H256, U256}, ethrpc::extensions::StateOverride, maplit::hashmap, @@ -9,16 +12,132 @@ use { collections::HashMap, fmt::{self, Display, Formatter}, str::FromStr, + sync::{Arc, Mutex}, }, web3::signing, }; +/// Balance override configuration arguments. +#[derive(clap::Parser)] +#[group(skip)] +pub struct Arguments { + /// Token configuration for simulated balances on verified quotes. This + /// allows the quote verification system to produce verified quotes for + /// traders without sufficient balance for the configured token pairs. + /// + /// The expected format is a comma separated list of `${ADDR}@${SLOT}`, + /// where `ADDR` is the token address and `SLOT` is the Solidity storage + /// slot for the balances mapping. For example for WETH: + /// `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2@3`. + #[clap(long, env, default_value_t)] + pub quote_token_balance_overrides: TokenConfiguration, + + /// Enable automatic detection of token balance overrides. Note that + /// pre-configured values with the `--quote-token-balance-overrides` flag + /// will take precedence. + #[clap(long, env, action = clap::ArgAction::Set, default_value_t)] + pub quote_autodetect_token_balance_overrides: bool, +} + +impl Arguments { + const CACHE_SIZE: usize = 1000; + + /// Creates a balance overrides instance from the current configuration. + pub fn init(&self, simulator: Arc) -> Arc { + Arc::new(BalanceOverrides { + hardcoded: self.quote_token_balance_overrides.0.clone(), + detector: self.quote_autodetect_token_balance_overrides.then(|| { + ( + Detector::new(simulator), + Mutex::new(SizedCache::with_size(Self::CACHE_SIZE)), + ) + }), + }) + } +} + +impl Display for Arguments { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + let Self { + quote_token_balance_overrides, + quote_autodetect_token_balance_overrides, + } = self; + + writeln!( + f, + "quote_token_balance_overrides: {:?}", + quote_token_balance_overrides + )?; + writeln!( + f, + "quote_autodetect_token_balance_overrides: {:?}", + quote_autodetect_token_balance_overrides + )?; + + Ok(()) + } +} + +/// Token configurations for the `BalanceOverriding` component. +#[derive(Clone, Debug, Default)] +pub struct TokenConfiguration(HashMap); + +impl Display for TokenConfiguration { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + let format_entry = + |f: &mut Formatter, (addr, strategy): (&Address, &Strategy)| match strategy { + Strategy::Mapping { slot } => write!(f, "{addr:?}@{slot}"), + }; + + let mut entries = self.0.iter(); + + let Some(first) = entries.next() else { + return Ok(()); + }; + format_entry(f, first)?; + + for entry in entries { + f.write_str(",")?; + format_entry(f, entry)?; + } + + Ok(()) + } +} + +impl FromStr for TokenConfiguration { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + if s.is_empty() { + return Ok(Self::default()); + } + + let entries = s + .split(',') + .map(|part| -> Result<_, Self::Err> { + let (addr, slot) = part + .split_once('@') + .context("expected {addr}@{slot} format")?; + Ok(( + addr.parse()?, + Strategy::Mapping { + slot: slot.parse()?, + }, + )) + }) + .collect::>()?; + Ok(Self(entries)) + } +} + /// A component that can provide balance overrides for tokens. /// /// This allows a wider range of verified quotes to work, even when balances /// are not available for the quoter. +#[async_trait::async_trait] pub trait BalanceOverriding: Send + Sync + 'static { - fn state_override(&self, request: &BalanceOverrideRequest) -> Option; + async fn state_override(&self, request: BalanceOverrideRequest) -> Option; } /// Parameters for computing a balance override request. @@ -31,10 +150,6 @@ pub struct BalanceOverrideRequest { pub amount: U256, } -/// A simple configuration-based balance override provider. -#[derive(Clone, Debug, Default)] -pub struct ConfigurationBalanceOverrides(HashMap); - /// Balance override strategy for a token. #[derive(Clone, Debug)] pub enum Strategy { @@ -71,69 +186,73 @@ impl Strategy { } } -impl ConfigurationBalanceOverrides { - pub fn new(config: HashMap) -> Self { - Self(config) - } -} +type DetectorCache = Mutex>>; -impl BalanceOverriding for ConfigurationBalanceOverrides { - fn state_override(&self, request: &BalanceOverrideRequest) -> Option { - let strategy = self.0.get(&request.token)?; - let (key, value) = strategy.state_override(&request.holder, &request.amount); - Some(StateOverride { - state_diff: Some(hashmap! { key => value }), - ..Default::default() - }) - } +/// The default balance override provider. +#[derive(Debug, Default)] +pub struct BalanceOverrides { + /// The configured balance override strategies for tokens. + /// + /// These take priority over the auto-detection mechanism and are excluded + /// from the cache in order to prevent them from getting cleaned up by + /// the caching policy. + hardcoded: HashMap, + /// The balance override detector and its cache. Set to `None` if + /// auto-detection is not enabled. + detector: Option<(Detector, DetectorCache)>, } -impl Display for ConfigurationBalanceOverrides { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - let format_entry = - |f: &mut Formatter, (addr, strategy): (&Address, &Strategy)| match strategy { - Strategy::Mapping { slot } => write!(f, "{addr:?}@{slot}"), - }; +impl BalanceOverrides { + async fn cached_detection(&self, token: Address) -> Option { + let (detector, cache) = self.detector.as_ref()?; + tracing::trace!(?token, "attempting to auto-detect"); - let mut entries = self.0.iter(); + { + let mut cache = cache.lock().unwrap(); + if let Some(strategy) = cache.cache_get(&token) { + tracing::trace!(?token, "cache hit"); + return strategy.clone(); + } + } - let Some(first) = entries.next() else { - return Ok(()); - }; - format_entry(f, first)?; + let strategy = detector.detect(token).await; - for entry in entries { - f.write_str(",")?; - format_entry(f, entry)?; + // Only cache when we successfully detect the token, or we can't find + // it. Anything else is likely a temporary simulator (i.e. node) failure + // which we don't want to cache. + if matches!(&strategy, Ok(_) | Err(DetectionError::NotFound)) { + tracing::debug!(?token, ?strategy, "caching auto-detected strategy"); + let cached_strategy = strategy.as_ref().ok().cloned(); + cache.lock().unwrap().cache_set(token, cached_strategy); + } else { + tracing::warn!( + ?token, + ?strategy, + "error auto-detecting token balance override strategy" + ); } - Ok(()) + strategy.ok() } } -impl FromStr for ConfigurationBalanceOverrides { - type Err = anyhow::Error; +#[async_trait::async_trait] +impl BalanceOverriding for BalanceOverrides { + async fn state_override(&self, request: BalanceOverrideRequest) -> Option { + let strategy = if let Some(strategy) = self.hardcoded.get(&request.token) { + tracing::trace!(token = ?request.token, "using pre-configured balance override strategy"); + Some(strategy.clone()) + } else { + self.cached_detection(request.token).await + }?; - fn from_str(s: &str) -> Result { - if s.is_empty() { - return Ok(Self::default()); - } + let (key, value) = strategy.state_override(&request.holder, &request.amount); + tracing::trace!(?strategy, ?key, ?value, "overriding token balance"); - let entries = s - .split(',') - .map(|part| -> Result<_, Self::Err> { - let (addr, slot) = part - .split_once('@') - .context("expected {addr}@{slot} format")?; - Ok(( - addr.parse()?, - Strategy::Mapping { - slot: slot.parse()?, - }, - )) - }) - .collect::>()?; - Ok(Self(entries)) + Some(StateOverride { + state_diff: Some(hashmap! { key => value }), + ..Default::default() + }) } } @@ -141,20 +260,25 @@ impl FromStr for ConfigurationBalanceOverrides { mod tests { use {super::*, hex_literal::hex}; - #[test] - fn balance_override_computation() { - let balance_overrides = ConfigurationBalanceOverrides::new(hashmap! { - addr!("DEf1CA1fb7FBcDC777520aa7f396b4E015F497aB") => Strategy::Mapping { - slot: U256::from(0), + #[tokio::test] + async fn balance_override_computation() { + let balance_overrides = BalanceOverrides { + hardcoded: hashmap! { + addr!("DEf1CA1fb7FBcDC777520aa7f396b4E015F497aB") => Strategy::Mapping { + slot: U256::from(0), + }, }, - }); + ..Default::default() + }; assert_eq!( - balance_overrides.state_override(&BalanceOverrideRequest { - token: addr!("DEf1CA1fb7FBcDC777520aa7f396b4E015F497aB"), - holder: addr!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045"), - amount: 0x42_u64.into(), - }), + balance_overrides + .state_override(BalanceOverrideRequest { + token: addr!("DEf1CA1fb7FBcDC777520aa7f396b4E015F497aB"), + holder: addr!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045"), + amount: 0x42_u64.into(), + }) + .await, Some(StateOverride { state_diff: Some(hashmap! { H256(hex!("fca351f4d96129454cfc8ef7930b638ac71fea35eb69ee3b8d959496beb04a33")) => @@ -189,15 +313,17 @@ mod tests { // ``` } - #[test] - fn balance_overrides_none_for_unknown_tokens() { - let balance_overrides = ConfigurationBalanceOverrides::default(); + #[tokio::test] + async fn balance_overrides_none_for_unknown_tokens() { + let balance_overrides = BalanceOverrides::default(); assert_eq!( - balance_overrides.state_override(&BalanceOverrideRequest { - token: addr!("0000000000000000000000000000000000000000"), - holder: addr!("0000000000000000000000000000000000000001"), - amount: U256::zero(), - }), + balance_overrides + .state_override(BalanceOverrideRequest { + token: addr!("0000000000000000000000000000000000000000"), + holder: addr!("0000000000000000000000000000000000000001"), + amount: U256::zero(), + }) + .await, None, ); } diff --git a/crates/shared/src/price_estimation/trade_verifier/balance_overrides/detector.rs b/crates/shared/src/price_estimation/trade_verifier/balance_overrides/detector.rs index 0ce48951e3..d8795b7ce4 100644 --- a/crates/shared/src/price_estimation/trade_verifier/balance_overrides/detector.rs +++ b/crates/shared/src/price_estimation/trade_verifier/balance_overrides/detector.rs @@ -5,7 +5,10 @@ use { ethcontract::{Address, U256}, ethrpc::extensions::StateOverride, maplit::hashmap, - std::sync::Arc, + std::{ + fmt::{self, Debug, Formatter}, + sync::Arc, + }, thiserror::Error, web3::{signing::keccak256, types::CallRequest}, }; @@ -13,11 +16,11 @@ use { /// A heuristic balance override detector based on `eth_call` simulations. /// /// This has the exact same node requirements as trade verification. +#[derive(Clone)] pub struct Detector { simulator: Arc, } -#[allow(dead_code)] impl Detector { /// Number of different slots to try out. const TRIES: u8 = 25; @@ -90,6 +93,14 @@ impl Detector { } } +impl Debug for Detector { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + f.debug_struct("Detector") + .field("simulator", &format_args!("Arc")) + .finish() + } +} + /// An error detecting the balance override strategy for a token. #[derive(Debug, Error)] pub enum DetectionError {