From 546fa7004045d55a43f89e7da9c6027dab0b350d Mon Sep 17 00:00:00 2001 From: Nicholas Rodrigues Lordello Date: Thu, 5 Dec 2024 14:51:18 +0100 Subject: [PATCH 1/5] Introduce Component for Balance Overrides (#3125) # Description This PR is the first in a stack to add a system for overriding balances so that more quotes can be verified. One limitation with the current quote verification system, is that it requires that the `from` account in the quote has the sell token balance available (or available after a pre-hook is executed) in order for the quote to be properly verified. This isn't always possible for all flows (and notably flows at Safe, where transactions to prepare the balance happens at the same time as the `setPreSignature` transaction executes, so after the quote). The overall solution I would propose (hopefully a pragmatic one that isn't considered _too_ hacky) would be enable special handling for the most commonly traded tokens, by configuring for each token how the storage slot is computed for the token balance. This way, you could maintain a file that contains a `token => computation_strategy` map for the most popular tokens allowing trades to be verified even for quotes from users without the balance available. This PR is the first piece for this overall solution, which introduces a component for computing storage slots needed for overriding balances for `eth_call` simulations. If this strategy is accepted, in a follow up PRs I would: 1. Add the component to the trade verifier and use it to fund the trader when simulating quotes (I have an idea on how to do this: you would override the balance of the `Solver` simulation entrypoint, which would top up the `Trader` balance if needed; this way the missing balance can be reported as part of the simulation and logged). 2. Pipe configuration to the trade verifier and balance overrides component # Changes - [x] Introduces a new `BalanceOverriding` component ## How to test Added unit tests verifying logic. --- .../src/price_estimation/trade_verifier.rs | 2 + .../trade_verifier/balance_overrides.rs | 130 ++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 crates/shared/src/price_estimation/trade_verifier/balance_overrides.rs diff --git a/crates/shared/src/price_estimation/trade_verifier.rs b/crates/shared/src/price_estimation/trade_verifier.rs index 02e20a24d9..7107ac5ff0 100644 --- a/crates/shared/src/price_estimation/trade_verifier.rs +++ b/crates/shared/src/price_estimation/trade_verifier.rs @@ -1,3 +1,5 @@ +pub mod balance_overrides; + use { super::{Estimate, Verification}, crate::{ diff --git a/crates/shared/src/price_estimation/trade_verifier/balance_overrides.rs b/crates/shared/src/price_estimation/trade_verifier/balance_overrides.rs new file mode 100644 index 0000000000..e8992efb6c --- /dev/null +++ b/crates/shared/src/price_estimation/trade_verifier/balance_overrides.rs @@ -0,0 +1,130 @@ +use { + ethcontract::{Address, H256, U256}, + ethrpc::extensions::StateOverride, + maplit::hashmap, + std::collections::HashMap, + web3::signing, +}; + +/// 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. +pub trait BalanceOverriding { + fn state_override(&self, request: &BalanceOverrideRequest) -> Option; +} + +/// Parameters for computing a balance override request. +pub struct BalanceOverrideRequest { + /// The token for the override. + pub token: Address, + /// The account to override the balance for. + pub holder: Address, + /// The token amount (in atoms) to set the balance to. + pub amount: U256, +} + +/// A simple configuration-based balance override provider. +#[derive(Clone, Debug, Default)] +pub struct ConfigurationBalanceOverrides(HashMap); + +#[derive(Clone, Debug)] +pub enum Strategy { + Mapping { slot: U256 }, +} + +impl ConfigurationBalanceOverrides { + pub fn new(config: HashMap) -> Self { + Self(config) + } +} + +impl BalanceOverriding for ConfigurationBalanceOverrides { + fn state_override(&self, request: &BalanceOverrideRequest) -> Option { + let strategy = self.0.get(&request.token)?; + match strategy { + Strategy::Mapping { slot } => Some(StateOverride { + state_diff: Some(hashmap! { + address_mapping_storage_slot(slot, &request.holder) => request.amount, + }), + ..Default::default() + }), + } + } +} + +/// Computes the storage slot where the value is stored for Solidity mappings +/// of the form `mapping(address => ...)`. +/// +/// See . +fn address_mapping_storage_slot(slot: &U256, address: &Address) -> H256 { + let mut buf = [0; 64]; + buf[12..32].copy_from_slice(address.as_fixed_bytes()); + slot.to_big_endian(&mut buf[32..64]); + H256(signing::keccak256(&buf)) +} + +#[cfg(test)] +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), + }, + }); + + assert_eq!( + balance_overrides.state_override(&BalanceOverrideRequest { + token: addr!("DEf1CA1fb7FBcDC777520aa7f396b4E015F497aB"), + holder: addr!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045"), + amount: 0x42_u64.into(), + }), + Some(StateOverride { + state_diff: Some(hashmap! { + H256(hex!("fca351f4d96129454cfc8ef7930b638ac71fea35eb69ee3b8d959496beb04a33")) => 0x42_u64.into() + }), + ..Default::default() + }), + ); + + // You can verify the state override computation is correct by running: + // ``` + // curl -X POST $RPC -H 'Content-Type: application/data' --data '{ + // "jsonrpc": "2.0", + // "id": 0, + // "method": "eth_call", + // "params": [ + // { + // "to": "0xDEf1CA1fb7FBcDC777520aa7f396b4E015F497aB", + // "data": "0x70a08231000000000000000000000000d8dA6BF26964aF9D7eEd9e03E53415D37aA96045" + // }, + // "latest", + // { + // "0xDEf1CA1fb7FBcDC777520aa7f396b4E015F497aB": { + // "stateDiff": { + // "0xfca351f4d96129454cfc8ef7930b638ac71fea35eb69ee3b8d959496beb04a33": + // "0x0000000000000000000000000000000000000000000000000000000000000042" + // } + // } + // } + // ] + // }' + // ``` + } + + #[test] + fn balance_overrides_none_for_unknown_tokens() { + let balance_overrides = ConfigurationBalanceOverrides::default(); + assert_eq!( + balance_overrides.state_override(&BalanceOverrideRequest { + token: addr!("0000000000000000000000000000000000000000"), + holder: addr!("0000000000000000000000000000000000000001"), + amount: U256::zero(), + }), + None, + ); + } +} From e75a277e922e6c50ea169eadb8e667927c14c831 Mon Sep 17 00:00:00 2001 From: Nicholas Rodrigues Lordello Date: Thu, 5 Dec 2024 16:39:41 +0100 Subject: [PATCH 2/5] Simulated Token Balances for Verified Quotes (#3147) # Description This PR is a follow up to #3125 and uses the component introduced in the aforementioned PR for setting up a simulated token balance using state overrides in order for quote verification to work even when the trader does not have sufficient balance. # Changes The way it works is by configuring known mapping slots for the `mapping(address => uint256) balances` in ERC20 token contract implementations and using this to compute the slot for overriding a separate account's token balance (the `Spardose`), which can prefund the trader during quote simualtions. We intentionally do not override the trader's or solver's balance in order to not interfere with the settlement process: > Technically a solver could have private inventory they would like to > use for the solution instead of transfering it to the trader. _Posted by @MartinquaXD_ Note that the type of the state override changed slightly. This is because it was wrong to begin with. Node implementations I tested with (Geth and Anvil) expect both the slot and the value for state overrides to be exactly 32-bytes long (so `H256`). I guess this feature of the state override in the `ethrpc` crate was not used in the past and therefore no one noticed :shrug:. - [x] Adds command line configuration for token balance overrides - [x] Adds logic to the trades verifier to setup state overrides for take token balances for the configured tokens - [x] Adds logic in the settlement simulation to try and fund the trader if they are missing balances and balance overrides are enabled - [x] Fixes to the `StateOverride` type and serialization ### Test Plan Added an E2E test that uses the new token balance override feature in order to produce a verified quote for a trader with no balances. Note that commenting out the API arguments causes the test to fail as expected. > This PR is the combination of two original PRs mentioned in #3125: > * https://github.com/nlordell/cowprotocol-services/pull/1 > * https://github.com/nlordell/cowprotocol-services/pull/2. --- crates/contracts/artifacts/Solver.json | 2 +- crates/contracts/artifacts/Spardose.json | 1 + crates/contracts/artifacts/Swapper.json | 2 +- crates/contracts/artifacts/Trader.json | 2 +- crates/contracts/build.rs | 3 +- crates/contracts/solidity/Makefile | 1 + crates/contracts/solidity/Solver.sol | 36 +++++-- crates/contracts/solidity/Spardose.sol | 32 ++++++ crates/contracts/solidity/Trader.sol | 3 - .../solidity/libraries/SafeERC20.sol | 17 ++- crates/contracts/src/lib.rs | 1 + crates/e2e/tests/e2e/quote_verification.rs | 102 +++++++++++++++++- crates/ethrpc/src/extensions.rs | 4 +- crates/shared/src/code_simulation.rs | 17 +-- crates/shared/src/price_estimation/factory.rs | 27 ++--- crates/shared/src/price_estimation/mod.rs | 18 ++++ .../src/price_estimation/trade_verifier.rs | 70 ++++++++++-- .../trade_verifier/balance_overrides.rs | 79 ++++++++++++-- 18 files changed, 353 insertions(+), 64 deletions(-) create mode 100644 crates/contracts/artifacts/Spardose.json create mode 100644 crates/contracts/solidity/Spardose.sol diff --git a/crates/contracts/artifacts/Solver.json b/crates/contracts/artifacts/Solver.json index f4de20dccc..0b3ffa8e18 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"},{"internalType":"bool","name":"mockPreconditions","type":"bool"}],"name":"swap","outputs":[{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256[]","name":"queriedBalances","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"}],"bytecode":"0x608060405234801561001057600080fd5b50610941806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80633bbb2e1d1461003b578063cc6b67a914610050575b600080fd5b61004e610049366004610600565b61007a565b005b61006361005e3660046106d5565b6101af565b6040516100719291906107bf565b60405180910390f35b60005a9050600173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff861614610147576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528616906370a0823190602401602060405180830381865afa15801561011e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610142919061080d565b610160565b8373ffffffffffffffffffffffffffffffffffffffff16315b8154600181018355600092835260209092209091015581156101a9575a6101879082610855565b6101939061116c61086e565b6000808282546101a3919061086e565b90915550505b50505050565b60006060333014610246576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f6f6e6c792073696d756c6174696f6e206c6f67696320697320616c6c6f77656460448201527f20746f2063616c6c202773776170272066756e6374696f6e0000000000000000606482015260840160405180910390fd5b82156102e5576040517f57d5a1d300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8e811660048301528c81166024830152604482018c90528a811660648301528d16906357d5a1d390608401600060405180830381600087803b1580156102cc57600080fd5b505af11580156102e0573d6000803e3d6000fd5b505050505b60405173ffffffffffffffffffffffffffffffffffffffff8716906000908181818181875af1925050503d806000811461033b576040519150601f19603f3d011682016040523d82523d6000602084013e610340565b606091505b50505061034e88888f6103c9565b6103598d86866104a1565b915061036688888f6103c9565b60018054806020026020016040519081016040528092919081815260200182805480156103b257602002820191906000526020600020905b81548152602001906001019080831161039e575b505050505090509b509b9950505050505050505050565b60005b828110156101a95730633bbb2e1d8585848181106103ec576103ec610881565b905060200201602081019061040191906108b0565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9182166004820152908516602482015260006044820152606401600060405180830381600087803b15801561047657600080fd5b505af115801561048a573d6000803e3d6000fd5b505050508080610499906108cd565b9150506103cc565b6000805a90506104fe84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505073ffffffffffffffffffffffffffffffffffffffff891692915050610520565b506000545a61050d9083610855565b6105179190610855565b95945050505050565b606061052e83600084610535565b9392505050565b606060008473ffffffffffffffffffffffffffffffffffffffff16848460405161055f9190610905565b60006040518083038185875af1925050503d806000811461059c576040519150601f19603f3d011682016040523d82523d6000602084013e6105a1565b606091505b5092509050806105b357815160208301fd5b509392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146105dd57600080fd5b50565b80356105eb816105bb565b919050565b803580151581146105eb57600080fd5b60008060006060848603121561061557600080fd5b8335610620816105bb565b92506020840135610630816105bb565b915061063e604085016105f0565b90509250925092565b60008083601f84011261065957600080fd5b50813567ffffffffffffffff81111561067157600080fd5b6020830191508360208260051b850101111561068c57600080fd5b9250929050565b60008083601f8401126106a557600080fd5b50813567ffffffffffffffff8111156106bd57600080fd5b60208301915083602082850101111561068c57600080fd5b60008060008060008060008060008060006101208c8e0312156106f757600080fd5b6107018c356105bb565b8b359a5061071260208d01356105bb565b60208c0135995061072560408d016105e0565b985060608c0135975061073a60808d016105e0565b965067ffffffffffffffff8060a08e0135111561075657600080fd5b6107668e60a08f01358f01610647565b909750955061077760c08e016105e0565b94508060e08e0135111561078a57600080fd5b5061079b8d60e08e01358e01610693565b90935091506107ad6101008d016105f0565b90509295989b509295989b9093969950565b6000604082018483526020604081850152818551808452606086019150828701935060005b81811015610800578451835293830193918301916001016107e4565b5090979650505050505050565b60006020828403121561081f57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561086857610868610826565b92915050565b8082018082111561086857610868610826565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156108c257600080fd5b813561052e816105bb565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036108fe576108fe610826565b5060010190565b6000825160005b81811015610926576020818601810151858301520161090c565b50600092019182525091905056fea164736f6c6343000811000a","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c80633bbb2e1d1461003b578063cc6b67a914610050575b600080fd5b61004e610049366004610600565b61007a565b005b61006361005e3660046106d5565b6101af565b6040516100719291906107bf565b60405180910390f35b60005a9050600173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff861614610147576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528616906370a0823190602401602060405180830381865afa15801561011e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610142919061080d565b610160565b8373ffffffffffffffffffffffffffffffffffffffff16315b8154600181018355600092835260209092209091015581156101a9575a6101879082610855565b6101939061116c61086e565b6000808282546101a3919061086e565b90915550505b50505050565b60006060333014610246576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f6f6e6c792073696d756c6174696f6e206c6f67696320697320616c6c6f77656460448201527f20746f2063616c6c202773776170272066756e6374696f6e0000000000000000606482015260840160405180910390fd5b82156102e5576040517f57d5a1d300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8e811660048301528c81166024830152604482018c90528a811660648301528d16906357d5a1d390608401600060405180830381600087803b1580156102cc57600080fd5b505af11580156102e0573d6000803e3d6000fd5b505050505b60405173ffffffffffffffffffffffffffffffffffffffff8716906000908181818181875af1925050503d806000811461033b576040519150601f19603f3d011682016040523d82523d6000602084013e610340565b606091505b50505061034e88888f6103c9565b6103598d86866104a1565b915061036688888f6103c9565b60018054806020026020016040519081016040528092919081815260200182805480156103b257602002820191906000526020600020905b81548152602001906001019080831161039e575b505050505090509b509b9950505050505050505050565b60005b828110156101a95730633bbb2e1d8585848181106103ec576103ec610881565b905060200201602081019061040191906108b0565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9182166004820152908516602482015260006044820152606401600060405180830381600087803b15801561047657600080fd5b505af115801561048a573d6000803e3d6000fd5b505050508080610499906108cd565b9150506103cc565b6000805a90506104fe84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505073ffffffffffffffffffffffffffffffffffffffff891692915050610520565b506000545a61050d9083610855565b6105179190610855565b95945050505050565b606061052e83600084610535565b9392505050565b606060008473ffffffffffffffffffffffffffffffffffffffff16848460405161055f9190610905565b60006040518083038185875af1925050503d806000811461059c576040519150601f19603f3d011682016040523d82523d6000602084013e6105a1565b606091505b5092509050806105b357815160208301fd5b509392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146105dd57600080fd5b50565b80356105eb816105bb565b919050565b803580151581146105eb57600080fd5b60008060006060848603121561061557600080fd5b8335610620816105bb565b92506020840135610630816105bb565b915061063e604085016105f0565b90509250925092565b60008083601f84011261065957600080fd5b50813567ffffffffffffffff81111561067157600080fd5b6020830191508360208260051b850101111561068c57600080fd5b9250929050565b60008083601f8401126106a557600080fd5b50813567ffffffffffffffff8111156106bd57600080fd5b60208301915083602082850101111561068c57600080fd5b60008060008060008060008060008060006101208c8e0312156106f757600080fd5b6107018c356105bb565b8b359a5061071260208d01356105bb565b60208c0135995061072560408d016105e0565b985060608c0135975061073a60808d016105e0565b965067ffffffffffffffff8060a08e0135111561075657600080fd5b6107668e60a08f01358f01610647565b909750955061077760c08e016105e0565b94508060e08e0135111561078a57600080fd5b5061079b8d60e08e01358e01610693565b90935091506107ad6101008d016105f0565b90509295989b509295989b9093969950565b6000604082018483526020604081850152818551808452606086019150828701935060005b81811015610800578451835293830193918301916001016107e4565b5090979650505050505050565b60006020828403121561081f57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561086857610868610826565b92915050565b8082018082111561086857610868610826565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156108c257600080fd5b813561052e816105bb565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036108fe576108fe610826565b5060010190565b6000825160005b81811015610926576020818601810151858301520161090c565b50600092019182525091905056fea164736f6c6343000811000a","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":"0x608060405234801561001057600080fd5b50610b26806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806317b86b161461003b5780633bbb2e1d14610065575b600080fd5b61004e610049366004610851565b61007a565b60405161005c92919061093c565b60405180910390f35b61007861007336600461098a565b6103cf565b005b60006060333014610112576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f6f6e6c792073696d756c6174696f6e206c6f67696320697320616c6c6f77656460448201527f20746f2063616c6c202773776170272066756e6374696f6e000000000000000060648201526084015b60405180910390fd5b8251156102e4576040517f57d5a1d300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8e811660048301528c81166024830152604482018c90528a811660648301528d16906357d5a1d390608401600060405180830381600087803b15801561019957600080fd5b505af11580156101ad573d6000803e3d6000fd5b50505060208401516040517fc56cca8300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8f811660048301528e81166024830152604482018e9052909116915063c56cca83906064016020604051808303816000875af1158015610234573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025891906109d5565b6102e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f74726164657220646f6573206e6f74206861766520656e6f7567682073656c6c60448201527f20746f6b656e00000000000000000000000000000000000000000000000000006064820152608401610109565b60008673ffffffffffffffffffffffffffffffffffffffff16600060405160006040518083038185875af1925050503d806000811461033f576040519150601f19603f3d011682016040523d82523d6000602084013e610344565b606091505b505090505061035488888f610504565b61035f8d86866105dc565b915061036c88888f610504565b60018054806020026020016040519081016040528092919081815260200182805480156103b857602002820191906000526020600020905b8154815260200190600101908083116103a4575b505050505090509b509b9950505050505050505050565b60005a9050600173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff86161461049c576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528616906370a0823190602401602060405180830381865afa158015610473573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049791906109f2565b6104b5565b8373ffffffffffffffffffffffffffffffffffffffff16315b8154600181018355600092835260209092209091015581156104fe575a6104dc9082610a3a565b6104e89061116c610a53565b6000808282546104f89190610a53565b90915550505b50505050565b60005b828110156104fe5730633bbb2e1d85858481811061052757610527610a66565b905060200201602081019061053c9190610a95565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9182166004820152908516602482015260006044820152606401600060405180830381600087803b1580156105b157600080fd5b505af11580156105c5573d6000803e3d6000fd5b5050505080806105d490610ab2565b915050610507565b6000805a905061063984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505073ffffffffffffffffffffffffffffffffffffffff89169291505061065b565b506000545a6106489083610a3a565b6106529190610a3a565b95945050505050565b606061066983600084610670565b9392505050565b606060008473ffffffffffffffffffffffffffffffffffffffff16848460405161069a9190610aea565b60006040518083038185875af1925050503d80600081146106d7576040519150601f19603f3d011682016040523d82523d6000602084013e6106dc565b606091505b5092509050806106ee57815160208301fd5b509392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461071857600080fd5b50565b8035610726816106f6565b919050565b60008083601f84011261073d57600080fd5b50813567ffffffffffffffff81111561075557600080fd5b6020830191508360208260051b850101111561077057600080fd5b9250929050565b60008083601f84011261078957600080fd5b50813567ffffffffffffffff8111156107a157600080fd5b60208301915083602082850101111561077057600080fd5b801515811461071857600080fd5b6000604082840312156107d957600080fd5b6040516040810181811067ffffffffffffffff82111715610823577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040529050808235610834816107b9565b81526020830135610844816106f6565b6020919091015292915050565b60008060008060008060008060008060006101408c8e03121561087357600080fd5b61087d8c356106f6565b8b359a5061088e60208d01356106f6565b60208c013599506108a160408d0161071b565b985060608c013597506108b660808d0161071b565b965067ffffffffffffffff8060a08e013511156108d257600080fd5b6108e28e60a08f01358f0161072b565b90975095506108f360c08e0161071b565b94508060e08e0135111561090657600080fd5b506109178d60e08e01358e01610777565b909350915061092a8d6101008e016107c7565b90509295989b509295989b9093969950565b6000604082018483526020604081850152818551808452606086019150828701935060005b8181101561097d57845183529383019391830191600101610961565b5090979650505050505050565b60008060006060848603121561099f57600080fd5b83356109aa816106f6565b925060208401356109ba816106f6565b915060408401356109ca816107b9565b809150509250925092565b6000602082840312156109e757600080fd5b8151610669816107b9565b600060208284031215610a0457600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610a4d57610a4d610a0b565b92915050565b80820180821115610a4d57610a4d610a0b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215610aa757600080fd5b8135610669816106f6565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610ae357610ae3610a0b565b5060010190565b6000825160005b81811015610b0b5760208186018101518583015201610af1565b50600092019182525091905056fea164736f6c6343000811000a","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c806317b86b161461003b5780633bbb2e1d14610065575b600080fd5b61004e610049366004610851565b61007a565b60405161005c92919061093c565b60405180910390f35b61007861007336600461098a565b6103cf565b005b60006060333014610112576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f6f6e6c792073696d756c6174696f6e206c6f67696320697320616c6c6f77656460448201527f20746f2063616c6c202773776170272066756e6374696f6e000000000000000060648201526084015b60405180910390fd5b8251156102e4576040517f57d5a1d300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8e811660048301528c81166024830152604482018c90528a811660648301528d16906357d5a1d390608401600060405180830381600087803b15801561019957600080fd5b505af11580156101ad573d6000803e3d6000fd5b50505060208401516040517fc56cca8300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8f811660048301528e81166024830152604482018e9052909116915063c56cca83906064016020604051808303816000875af1158015610234573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025891906109d5565b6102e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f74726164657220646f6573206e6f74206861766520656e6f7567682073656c6c60448201527f20746f6b656e00000000000000000000000000000000000000000000000000006064820152608401610109565b60008673ffffffffffffffffffffffffffffffffffffffff16600060405160006040518083038185875af1925050503d806000811461033f576040519150601f19603f3d011682016040523d82523d6000602084013e610344565b606091505b505090505061035488888f610504565b61035f8d86866105dc565b915061036c88888f610504565b60018054806020026020016040519081016040528092919081815260200182805480156103b857602002820191906000526020600020905b8154815260200190600101908083116103a4575b505050505090509b509b9950505050505050505050565b60005a9050600173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff86161461049c576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528616906370a0823190602401602060405180830381865afa158015610473573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049791906109f2565b6104b5565b8373ffffffffffffffffffffffffffffffffffffffff16315b8154600181018355600092835260209092209091015581156104fe575a6104dc9082610a3a565b6104e89061116c610a53565b6000808282546104f89190610a53565b90915550505b50505050565b60005b828110156104fe5730633bbb2e1d85858481811061052757610527610a66565b905060200201602081019061053c9190610a95565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9182166004820152908516602482015260006044820152606401600060405180830381600087803b1580156105b157600080fd5b505af11580156105c5573d6000803e3d6000fd5b5050505080806105d490610ab2565b915050610507565b6000805a905061063984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505073ffffffffffffffffffffffffffffffffffffffff89169291505061065b565b506000545a6106489083610a3a565b6106529190610a3a565b95945050505050565b606061066983600084610670565b9392505050565b606060008473ffffffffffffffffffffffffffffffffffffffff16848460405161069a9190610aea565b60006040518083038185875af1925050503d80600081146106d7576040519150601f19603f3d011682016040523d82523d6000602084013e6106dc565b606091505b5092509050806106ee57815160208301fd5b509392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461071857600080fd5b50565b8035610726816106f6565b919050565b60008083601f84011261073d57600080fd5b50813567ffffffffffffffff81111561075557600080fd5b6020830191508360208260051b850101111561077057600080fd5b9250929050565b60008083601f84011261078957600080fd5b50813567ffffffffffffffff8111156107a157600080fd5b60208301915083602082850101111561077057600080fd5b801515811461071857600080fd5b6000604082840312156107d957600080fd5b6040516040810181811067ffffffffffffffff82111715610823577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040529050808235610834816107b9565b81526020830135610844816106f6565b6020919091015292915050565b60008060008060008060008060008060006101408c8e03121561087357600080fd5b61087d8c356106f6565b8b359a5061088e60208d01356106f6565b60208c013599506108a160408d0161071b565b985060608c013597506108b660808d0161071b565b965067ffffffffffffffff8060a08e013511156108d257600080fd5b6108e28e60a08f01358f0161072b565b90975095506108f360c08e0161071b565b94508060e08e0135111561090657600080fd5b506109178d60e08e01358e01610777565b909350915061092a8d6101008e016107c7565b90509295989b509295989b9093969950565b6000604082018483526020604081850152818551808452606086019150828701935060005b8181101561097d57845183529383019391830191600101610961565b5090979650505050505050565b60008060006060848603121561099f57600080fd5b83356109aa816106f6565b925060208401356109ba816106f6565b915060408401356109ca816107b9565b809150509250925092565b6000602082840312156109e757600080fd5b8151610669816107b9565b600060208284031215610a0457600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610a4d57610a4d610a0b565b92915050565b80820180821115610a4d57610a4d610a0b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215610aa757600080fd5b8135610669816106f6565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610ae357610ae3610a0b565b5060010190565b6000825160005b81811015610b0b5760208186018101518583015201610af1565b50600092019182525091905056fea164736f6c6343000811000a","devdoc":{"methods":{}},"userdoc":{"methods":{}}} diff --git a/crates/contracts/artifacts/Spardose.json b/crates/contracts/artifacts/Spardose.json new file mode 100644 index 0000000000..08787fb5a7 --- /dev/null +++ b/crates/contracts/artifacts/Spardose.json @@ -0,0 +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":{}}} diff --git a/crates/contracts/artifacts/Swapper.json b/crates/contracts/artifacts/Swapper.json index 3b4420dd93..7f6566ee0d 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":"0x608060405234801561001057600080fd5b506111c8806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80631626ba7e1461003b5780639ed280dd146100a7575b600080fd5b610071610049366004610b03565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b6100ba6100b5366004610bbc565b6100c8565b60405190815260200161009e565b6000602085018035906100db9087610c49565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610147573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016b9190610c66565b1015610179575060006108b8565b6102178673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101eb9190610c7f565b60006101fa6020890189610c49565b73ffffffffffffffffffffffffffffffffffffffff1691906108c1565b61029a8673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610265573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102899190610c7f565b602087018035906101fa9089610c49565b6040805160028082526060820183526000926020830190803683370190505090506102c86020870187610c49565b816000815181106102db576102db610ccb565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015261030b90860186610c49565b8160018151811061031e5761031e610ccb565b73ffffffffffffffffffffffffffffffffffffffff92909216602092830291909101820152604080516002808252606082018352600093919290918301908036833701905050905085602001358160008151811061037e5761037e610ccb565b6020026020010181815250508660200135816001815181106103a2576103a2610ccb565b6020908102919091010152604080516001808252818301909252600091816020015b6104406040518061016001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600063ffffffff16815260200160008019168152602001600081526020016000815260200160008152602001606081525090565b8152602001906001900390816103c45790505090506040518061016001604052806000815260200160018152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001896020013581526020018860200135815260200163ffffffff801681526020016000801b815260200160008152602001604081526020016000815260200130604051602001610506919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528152508160008151811061052b5761052b610ccb565b602002602001018190525061053e610adc565b60208088013590610551908b018b610c49565b73ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e8c61057a60208c018c610c49565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa1580156105ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060e9190610c66565b101561078c5760408051600180825281830190925290816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610629575050815261066660208a018a610c49565b8151805160009061067957610679610ccb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9092169091526106ac908a018a610c49565b73ffffffffffffffffffffffffffffffffffffffff1663095ea7b36106d460208a018a610c49565b60405173ffffffffffffffffffffffffffffffffffffffff909116602482015260208a01356044820152606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b929092179091529050816000602002015160008151811061077c5761077c610ccb565b6020026020010151604001819052505b60408051600180825281830190925290816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816107a157505060208201526107dd86610d72565b602082015180516000906107f3576107f3610ccb565b60200260200101819052506108b18a73ffffffffffffffffffffffffffffffffffffffff166313d79a0b868686866040516024016108349493929190611071565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b9290921790915273ffffffffffffffffffffffffffffffffffffffff8d16915061099c565b9450505050505b95945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905290600090610954908616836109b1565b9050610995816040518060400160405280601a81526020017f5361666545524332303a20617070726f76616c206661696c65640000000000008152506109bf565b5050505050565b60006109aa83600084610a23565b9392505050565b60606109aa83600084610a56565b815115806109dc5750818060200190518101906109dc919061112a565b8190610a1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a15919061114c565b60405180910390fd5b505050565b60005a905060008083516020850186885af1610a43573d6000803e3d6000fd5b5a610a4e908261115f565b949350505050565b606060008473ffffffffffffffffffffffffffffffffffffffff168484604051610a80919061119f565b60006040518083038185875af1925050503d8060008114610abd576040519150601f19603f3d011682016040523d82523d6000602084013e610ac2565b606091505b509250905080610ad457815160208301fd5b509392505050565b60405180606001604052806003905b6060815260200190600190039081610aeb5790505090565b600080600060408486031215610b1857600080fd5b83359250602084013567ffffffffffffffff80821115610b3757600080fd5b818601915086601f830112610b4b57600080fd5b813581811115610b5a57600080fd5b876020828501011115610b6c57600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114610ba157600080fd5b50565b600060408284031215610bb657600080fd5b50919050565b60008060008060006101008688031215610bd557600080fd5b8535610be081610b7f565b9450610bef8760208801610ba4565b9350610bfe8760608801610ba4565b9250610c0d8760a08801610ba4565b915060e086013567ffffffffffffffff811115610c2957600080fd5b860160608189031215610c3b57600080fd5b809150509295509295909350565b600060208284031215610c5b57600080fd5b81356109aa81610b7f565b600060208284031215610c7857600080fd5b5051919050565b600060208284031215610c9157600080fd5b81516109aa81610b7f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040516060810167ffffffffffffffff81118282101715610d1d57610d1d610c9c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610d6a57610d6a610c9c565b604052919050565b600060608236031215610d8457600080fd5b610d8c610cfa565b8235610d9781610b7f565b815260208381013581830152604084013567ffffffffffffffff80821115610dbe57600080fd5b9085019036601f830112610dd157600080fd5b813581811115610de357610de3610c9c565b610e13847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610d23565b91508082523684828501011115610e2957600080fd5b808484018584013760009082019093019290925250604082015292915050565b60005b83811015610e64578181015183820152602001610e4c565b50506000910152565b60008151808452610e85816020860160208601610e49565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015610f975782840389528151610160815186528682015187870152604080830151610f1a8289018273ffffffffffffffffffffffffffffffffffffffff169052565b5050606082810151908701526080808301519087015260a08083015163ffffffff169087015260c0808301519087015260e080830151908701526101008083015190870152610120808301519087015261014091820151918601819052610f8381870183610e6d565b9a87019a9550505090840190600101610ed5565b5091979650505050505050565b6000826060808201846000805b6003811015610f97578584038952825180518086526020918201918087019190600582901b88018101865b8381101561105a578982037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00185528551805173ffffffffffffffffffffffffffffffffffffffff16835283810151848401526040908101519083018c90526110478c840182610e6d565b9684019695840195925050600101610fdc565b509c81019c97509590950194505050600101610fb1565b6080808252855190820181905260009060209060a0840190828901845b828110156110c057815173ffffffffffffffffffffffffffffffffffffffff168452928401929084019060010161108e565b5050508381038285015286518082528783019183019060005b818110156110f5578351835292840192918401916001016110d9565b505084810360408601526111098188610eb7565b92505050828103606084015261111f8185610fa4565b979650505050505050565b60006020828403121561113c57600080fd5b815180151581146109aa57600080fd5b6020815260006109aa6020830184610e6d565b81810381811115611199577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b92915050565b600082516111b1818460208701610e49565b919091019291505056fea164736f6c6343000811000a","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c80631626ba7e1461003b5780639ed280dd146100a7575b600080fd5b610071610049366004610b03565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b6100ba6100b5366004610bbc565b6100c8565b60405190815260200161009e565b6000602085018035906100db9087610c49565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610147573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016b9190610c66565b1015610179575060006108b8565b6102178673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101eb9190610c7f565b60006101fa6020890189610c49565b73ffffffffffffffffffffffffffffffffffffffff1691906108c1565b61029a8673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610265573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102899190610c7f565b602087018035906101fa9089610c49565b6040805160028082526060820183526000926020830190803683370190505090506102c86020870187610c49565b816000815181106102db576102db610ccb565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015261030b90860186610c49565b8160018151811061031e5761031e610ccb565b73ffffffffffffffffffffffffffffffffffffffff92909216602092830291909101820152604080516002808252606082018352600093919290918301908036833701905050905085602001358160008151811061037e5761037e610ccb565b6020026020010181815250508660200135816001815181106103a2576103a2610ccb565b6020908102919091010152604080516001808252818301909252600091816020015b6104406040518061016001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600063ffffffff16815260200160008019168152602001600081526020016000815260200160008152602001606081525090565b8152602001906001900390816103c45790505090506040518061016001604052806000815260200160018152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001896020013581526020018860200135815260200163ffffffff801681526020016000801b815260200160008152602001604081526020016000815260200130604051602001610506919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528152508160008151811061052b5761052b610ccb565b602002602001018190525061053e610adc565b60208088013590610551908b018b610c49565b73ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e8c61057a60208c018c610c49565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa1580156105ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060e9190610c66565b101561078c5760408051600180825281830190925290816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610629575050815261066660208a018a610c49565b8151805160009061067957610679610ccb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9092169091526106ac908a018a610c49565b73ffffffffffffffffffffffffffffffffffffffff1663095ea7b36106d460208a018a610c49565b60405173ffffffffffffffffffffffffffffffffffffffff909116602482015260208a01356044820152606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b929092179091529050816000602002015160008151811061077c5761077c610ccb565b6020026020010151604001819052505b60408051600180825281830190925290816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816107a157505060208201526107dd86610d72565b602082015180516000906107f3576107f3610ccb565b60200260200101819052506108b18a73ffffffffffffffffffffffffffffffffffffffff166313d79a0b868686866040516024016108349493929190611071565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b9290921790915273ffffffffffffffffffffffffffffffffffffffff8d16915061099c565b9450505050505b95945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905290600090610954908616836109b1565b9050610995816040518060400160405280601a81526020017f5361666545524332303a20617070726f76616c206661696c65640000000000008152506109bf565b5050505050565b60006109aa83600084610a23565b9392505050565b60606109aa83600084610a56565b815115806109dc5750818060200190518101906109dc919061112a565b8190610a1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a15919061114c565b60405180910390fd5b505050565b60005a905060008083516020850186885af1610a43573d6000803e3d6000fd5b5a610a4e908261115f565b949350505050565b606060008473ffffffffffffffffffffffffffffffffffffffff168484604051610a80919061119f565b60006040518083038185875af1925050503d8060008114610abd576040519150601f19603f3d011682016040523d82523d6000602084013e610ac2565b606091505b509250905080610ad457815160208301fd5b509392505050565b60405180606001604052806003905b6060815260200190600190039081610aeb5790505090565b600080600060408486031215610b1857600080fd5b83359250602084013567ffffffffffffffff80821115610b3757600080fd5b818601915086601f830112610b4b57600080fd5b813581811115610b5a57600080fd5b876020828501011115610b6c57600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114610ba157600080fd5b50565b600060408284031215610bb657600080fd5b50919050565b60008060008060006101008688031215610bd557600080fd5b8535610be081610b7f565b9450610bef8760208801610ba4565b9350610bfe8760608801610ba4565b9250610c0d8760a08801610ba4565b915060e086013567ffffffffffffffff811115610c2957600080fd5b860160608189031215610c3b57600080fd5b809150509295509295909350565b600060208284031215610c5b57600080fd5b81356109aa81610b7f565b600060208284031215610c7857600080fd5b5051919050565b600060208284031215610c9157600080fd5b81516109aa81610b7f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040516060810167ffffffffffffffff81118282101715610d1d57610d1d610c9c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610d6a57610d6a610c9c565b604052919050565b600060608236031215610d8457600080fd5b610d8c610cfa565b8235610d9781610b7f565b815260208381013581830152604084013567ffffffffffffffff80821115610dbe57600080fd5b9085019036601f830112610dd157600080fd5b813581811115610de357610de3610c9c565b610e13847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610d23565b91508082523684828501011115610e2957600080fd5b808484018584013760009082019093019290925250604082015292915050565b60005b83811015610e64578181015183820152602001610e4c565b50506000910152565b60008151808452610e85816020860160208601610e49565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015610f975782840389528151610160815186528682015187870152604080830151610f1a8289018273ffffffffffffffffffffffffffffffffffffffff169052565b5050606082810151908701526080808301519087015260a08083015163ffffffff169087015260c0808301519087015260e080830151908701526101008083015190870152610120808301519087015261014091820151918601819052610f8381870183610e6d565b9a87019a9550505090840190600101610ed5565b5091979650505050505050565b6000826060808201846000805b6003811015610f97578584038952825180518086526020918201918087019190600582901b88018101865b8381101561105a578982037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00185528551805173ffffffffffffffffffffffffffffffffffffffff16835283810151848401526040908101519083018c90526110478c840182610e6d565b9684019695840195925050600101610fdc565b509c81019c97509590950194505050600101610fb1565b6080808252855190820181905260009060209060a0840190828901845b828110156110c057815173ffffffffffffffffffffffffffffffffffffffff168452928401929084019060010161108e565b5050508381038285015286518082528783019183019060005b818110156110f5578351835292840192918401916001016110d9565b505084810360408601526111098188610eb7565b92505050828103606084015261111f8185610fa4565b979650505050505050565b60006020828403121561113c57600080fd5b815180151581146109aa57600080fd5b6020815260006109aa6020830184610e6d565b81810381811115611199577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b92915050565b600082516111b1818460208701610e49565b919091019291505056fea164736f6c6343000811000a","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":"0x608060405234801561001057600080fd5b506111d5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80631626ba7e1461003b5780639ed280dd146100a7575b600080fd5b610071610049366004610b16565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b6100ba6100b5366004610bcf565b6100c8565b60405190815260200161009e565b6000602085018035906100db9087610c5c565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610147573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016b9190610c79565b1015610179575060006108b8565b6102178673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101eb9190610c92565b60006101fa6020890189610c5c565b73ffffffffffffffffffffffffffffffffffffffff1691906108c1565b61029a8673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610265573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102899190610c92565b602087018035906101fa9089610c5c565b6040805160028082526060820183526000926020830190803683370190505090506102c86020870187610c5c565b816000815181106102db576102db610cde565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015261030b90860186610c5c565b8160018151811061031e5761031e610cde565b73ffffffffffffffffffffffffffffffffffffffff92909216602092830291909101820152604080516002808252606082018352600093919290918301908036833701905050905085602001358160008151811061037e5761037e610cde565b6020026020010181815250508660200135816001815181106103a2576103a2610cde565b6020908102919091010152604080516001808252818301909252600091816020015b6104406040518061016001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600063ffffffff16815260200160008019168152602001600081526020016000815260200160008152602001606081525090565b8152602001906001900390816103c45790505090506040518061016001604052806000815260200160018152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001896020013581526020018860200135815260200163ffffffff801681526020016000801b815260200160008152602001604081526020016000815260200130604051602001610506919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528152508160008151811061052b5761052b610cde565b602002602001018190525061053e610aef565b60208088013590610551908b018b610c5c565b73ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e8c61057a60208c018c610c5c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa1580156105ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060e9190610c79565b101561078c5760408051600180825281830190925290816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610629575050815261066660208a018a610c5c565b8151805160009061067957610679610cde565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9092169091526106ac908a018a610c5c565b73ffffffffffffffffffffffffffffffffffffffff1663095ea7b36106d460208a018a610c5c565b60405173ffffffffffffffffffffffffffffffffffffffff909116602482015260208a01356044820152606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b929092179091529050816000602002015160008151811061077c5761077c610cde565b6020026020010151604001819052505b60408051600180825281830190925290816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816107a157505060208201526107dd86610d85565b602082015180516000906107f3576107f3610cde565b60200260200101819052506108b18a73ffffffffffffffffffffffffffffffffffffffff166313d79a0b868686866040516024016108349493929190611084565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b9290921790915273ffffffffffffffffffffffffffffffffffffffff8d16915061099c565b9450505050505b95945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905290600090610954908616836109b1565b9050610995816040518060400160405280601a81526020017f5361666545524332303a20617070726f76616c206661696c65640000000000008152506109bf565b5050505050565b60006109aa83600084610a0f565b9392505050565b60606109aa83600084610a42565b6109c882610ac8565b8190610a0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a01919061113d565b60405180910390fd5b505050565b60005a905060008083516020850186885af1610a2f573d6000803e3d6000fd5b5a610a3a9082611150565b949350505050565b606060008473ffffffffffffffffffffffffffffffffffffffff168484604051610a6c919061118a565b60006040518083038185875af1925050503d8060008114610aa9576040519150601f19603f3d011682016040523d82523d6000602084013e610aae565b606091505b509250905080610ac057815160208301fd5b509392505050565b6000815160001480610ae9575081806020019051810190610ae991906111a6565b92915050565b60405180606001604052806003905b6060815260200190600190039081610afe5790505090565b600080600060408486031215610b2b57600080fd5b83359250602084013567ffffffffffffffff80821115610b4a57600080fd5b818601915086601f830112610b5e57600080fd5b813581811115610b6d57600080fd5b876020828501011115610b7f57600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114610bb457600080fd5b50565b600060408284031215610bc957600080fd5b50919050565b60008060008060006101008688031215610be857600080fd5b8535610bf381610b92565b9450610c028760208801610bb7565b9350610c118760608801610bb7565b9250610c208760a08801610bb7565b915060e086013567ffffffffffffffff811115610c3c57600080fd5b860160608189031215610c4e57600080fd5b809150509295509295909350565b600060208284031215610c6e57600080fd5b81356109aa81610b92565b600060208284031215610c8b57600080fd5b5051919050565b600060208284031215610ca457600080fd5b81516109aa81610b92565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040516060810167ffffffffffffffff81118282101715610d3057610d30610caf565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610d7d57610d7d610caf565b604052919050565b600060608236031215610d9757600080fd5b610d9f610d0d565b8235610daa81610b92565b815260208381013581830152604084013567ffffffffffffffff80821115610dd157600080fd5b9085019036601f830112610de457600080fd5b813581811115610df657610df6610caf565b610e26847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610d36565b91508082523684828501011115610e3c57600080fd5b808484018584013760009082019093019290925250604082015292915050565b60005b83811015610e77578181015183820152602001610e5f565b50506000910152565b60008151808452610e98816020860160208601610e5c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015610faa5782840389528151610160815186528682015187870152604080830151610f2d8289018273ffffffffffffffffffffffffffffffffffffffff169052565b5050606082810151908701526080808301519087015260a08083015163ffffffff169087015260c0808301519087015260e080830151908701526101008083015190870152610120808301519087015261014091820151918601819052610f9681870183610e80565b9a87019a9550505090840190600101610ee8565b5091979650505050505050565b6000826060808201846000805b6003811015610faa578584038952825180518086526020918201918087019190600582901b88018101865b8381101561106d578982037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00185528551805173ffffffffffffffffffffffffffffffffffffffff16835283810151848401526040908101519083018c905261105a8c840182610e80565b9684019695840195925050600101610fef565b509c81019c97509590950194505050600101610fc4565b6080808252855190820181905260009060209060a0840190828901845b828110156110d357815173ffffffffffffffffffffffffffffffffffffffff16845292840192908401906001016110a1565b5050508381038285015286518082528783019183019060005b81811015611108578351835292840192918401916001016110ec565b5050848103604086015261111c8188610eca565b9250505082810360608401526111328185610fb7565b979650505050505050565b6020815260006109aa6020830184610e80565b81810381811115610ae9577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000825161119c818460208701610e5c565b9190910192915050565b6000602082840312156111b857600080fd5b815180151581146109aa57600080fdfea164736f6c6343000811000a","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c80631626ba7e1461003b5780639ed280dd146100a7575b600080fd5b610071610049366004610b16565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b6100ba6100b5366004610bcf565b6100c8565b60405190815260200161009e565b6000602085018035906100db9087610c5c565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610147573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016b9190610c79565b1015610179575060006108b8565b6102178673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101eb9190610c92565b60006101fa6020890189610c5c565b73ffffffffffffffffffffffffffffffffffffffff1691906108c1565b61029a8673ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610265573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102899190610c92565b602087018035906101fa9089610c5c565b6040805160028082526060820183526000926020830190803683370190505090506102c86020870187610c5c565b816000815181106102db576102db610cde565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015261030b90860186610c5c565b8160018151811061031e5761031e610cde565b73ffffffffffffffffffffffffffffffffffffffff92909216602092830291909101820152604080516002808252606082018352600093919290918301908036833701905050905085602001358160008151811061037e5761037e610cde565b6020026020010181815250508660200135816001815181106103a2576103a2610cde565b6020908102919091010152604080516001808252818301909252600091816020015b6104406040518061016001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600063ffffffff16815260200160008019168152602001600081526020016000815260200160008152602001606081525090565b8152602001906001900390816103c45790505090506040518061016001604052806000815260200160018152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001896020013581526020018860200135815260200163ffffffff801681526020016000801b815260200160008152602001604081526020016000815260200130604051602001610506919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528152508160008151811061052b5761052b610cde565b602002602001018190525061053e610aef565b60208088013590610551908b018b610c5c565b73ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e8c61057a60208c018c610c5c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa1580156105ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060e9190610c79565b101561078c5760408051600180825281830190925290816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610629575050815261066660208a018a610c5c565b8151805160009061067957610679610cde565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9092169091526106ac908a018a610c5c565b73ffffffffffffffffffffffffffffffffffffffff1663095ea7b36106d460208a018a610c5c565b60405173ffffffffffffffffffffffffffffffffffffffff909116602482015260208a01356044820152606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b929092179091529050816000602002015160008151811061077c5761077c610cde565b6020026020010151604001819052505b60408051600180825281830190925290816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816107a157505060208201526107dd86610d85565b602082015180516000906107f3576107f3610cde565b60200260200101819052506108b18a73ffffffffffffffffffffffffffffffffffffffff166313d79a0b868686866040516024016108349493929190611084565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e09390931b9290921790915273ffffffffffffffffffffffffffffffffffffffff8d16915061099c565b9450505050505b95945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905290600090610954908616836109b1565b9050610995816040518060400160405280601a81526020017f5361666545524332303a20617070726f76616c206661696c65640000000000008152506109bf565b5050505050565b60006109aa83600084610a0f565b9392505050565b60606109aa83600084610a42565b6109c882610ac8565b8190610a0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a01919061113d565b60405180910390fd5b505050565b60005a905060008083516020850186885af1610a2f573d6000803e3d6000fd5b5a610a3a9082611150565b949350505050565b606060008473ffffffffffffffffffffffffffffffffffffffff168484604051610a6c919061118a565b60006040518083038185875af1925050503d8060008114610aa9576040519150601f19603f3d011682016040523d82523d6000602084013e610aae565b606091505b509250905080610ac057815160208301fd5b509392505050565b6000815160001480610ae9575081806020019051810190610ae991906111a6565b92915050565b60405180606001604052806003905b6060815260200190600190039081610afe5790505090565b600080600060408486031215610b2b57600080fd5b83359250602084013567ffffffffffffffff80821115610b4a57600080fd5b818601915086601f830112610b5e57600080fd5b813581811115610b6d57600080fd5b876020828501011115610b7f57600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114610bb457600080fd5b50565b600060408284031215610bc957600080fd5b50919050565b60008060008060006101008688031215610be857600080fd5b8535610bf381610b92565b9450610c028760208801610bb7565b9350610c118760608801610bb7565b9250610c208760a08801610bb7565b915060e086013567ffffffffffffffff811115610c3c57600080fd5b860160608189031215610c4e57600080fd5b809150509295509295909350565b600060208284031215610c6e57600080fd5b81356109aa81610b92565b600060208284031215610c8b57600080fd5b5051919050565b600060208284031215610ca457600080fd5b81516109aa81610b92565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040516060810167ffffffffffffffff81118282101715610d3057610d30610caf565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610d7d57610d7d610caf565b604052919050565b600060608236031215610d9757600080fd5b610d9f610d0d565b8235610daa81610b92565b815260208381013581830152604084013567ffffffffffffffff80821115610dd157600080fd5b9085019036601f830112610de457600080fd5b813581811115610df657610df6610caf565b610e26847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610d36565b91508082523684828501011115610e3c57600080fd5b808484018584013760009082019093019290925250604082015292915050565b60005b83811015610e77578181015183820152602001610e5f565b50506000910152565b60008151808452610e98816020860160208601610e5c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015610faa5782840389528151610160815186528682015187870152604080830151610f2d8289018273ffffffffffffffffffffffffffffffffffffffff169052565b5050606082810151908701526080808301519087015260a08083015163ffffffff169087015260c0808301519087015260e080830151908701526101008083015190870152610120808301519087015261014091820151918601819052610f9681870183610e80565b9a87019a9550505090840190600101610ee8565b5091979650505050505050565b6000826060808201846000805b6003811015610faa578584038952825180518086526020918201918087019190600582901b88018101865b8381101561106d578982037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00185528551805173ffffffffffffffffffffffffffffffffffffffff16835283810151848401526040908101519083018c905261105a8c840182610e80565b9684019695840195925050600101610fef565b509c81019c97509590950194505050600101610fc4565b6080808252855190820181905260009060209060a0840190828901845b828110156110d357815173ffffffffffffffffffffffffffffffffffffffff16845292840192908401906001016110a1565b5050508381038285015286518082528783019183019060005b81811015611108578351835292840192918401916001016110ec565b5050848103604086015261111c8188610eca565b9250505082810360608401526111328185610fb7565b979650505050505050565b6020815260006109aa6020830184610e80565b81810381811115610ae9577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000825161119c818460208701610e5c565b9190910192915050565b6000602082840312156111b857600080fd5b815180151581146109aa57600080fdfea164736f6c6343000811000a","devdoc":{"methods":{}},"userdoc":{"methods":{}}} diff --git a/crates/contracts/artifacts/Trader.json b/crates/contracts/artifacts/Trader.json index f2a600e845..2614e657ac 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":"0x608060405234801561001057600080fd5b50610bb5806100206000396000f3fe60806040526004361061002d5760003560e01c80631626ba7e1461008657806357d5a1d3146100fe57610034565b3661003457005b600061007c6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525062010000939250506101209050565b9050805160208201f35b34801561009257600080fd5b506100c96100a136600461098b565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200160405180910390f35b34801561010a57600080fd5b5061011e610119366004610a2c565b6101a2565b005b606060008373ffffffffffffffffffffffffffffffffffffffff16836040516101499190610aa3565b600060405180830381855af49150503d8060008114610184576040519150601f19603f3d011682016040523d82523d6000602084013e610189565b606091505b50925090508061019b57815160208301fd5b5092915050565b6101aa61077f565b1561023c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f70726570617265537761702063616e206f6e6c792062652063616c6c6564206f60448201527f6e6365000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036103e7576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156102dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103009190610abf565b9050828110156103e55760006103168285610ad8565b905080471015610382576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6e6f7420656e6f7567682045544820746f2077726170000000000000000000006044820152606401610233565b8273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103ca57600080fd5b505af11580156103de573d6000803e3d6000fd5b5050505050505b505b60008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e308773ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610451573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104759190610b18565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa1580156104e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105099190610abf565b905082811015610654576105a48573ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610561573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105859190610b18565b73ffffffffffffffffffffffffffffffffffffffff86169060006107ba565b6106548573ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106169190610b18565b73ffffffffffffffffffffffffffffffffffffffff8616907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6107ba565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa1580156106c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e59190610abf565b905083811015610777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f74726164657220646f6573206e6f74206861766520656e6f7567682073656c6c60448201527f5f746f6b656e00000000000000000000000000000000000000000000000000006064820152608401610233565b505050505050565b6000806107ad60017f7f36ecad6e52bbe2ff70badce94360882c890b7877b16131c08eabfc635c9735610ad8565b8054600190915592915050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529060009061084d90861683610895565b905061088e816040518060400160405280601a81526020017f5361666545524332303a20617070726f76616c206661696c65640000000000008152506108aa565b5050505050565b60606108a383600084610905565b9392505050565b815115806108c75750818060200190518101906108c79190610b35565b8190610900576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102339190610b57565b505050565b606060008473ffffffffffffffffffffffffffffffffffffffff16848460405161092f9190610aa3565b60006040518083038185875af1925050503d806000811461096c576040519150601f19603f3d011682016040523d82523d6000602084013e610971565b606091505b50925090508061098357815160208301fd5b509392505050565b6000806000604084860312156109a057600080fd5b83359250602084013567ffffffffffffffff808211156109bf57600080fd5b818601915086601f8301126109d357600080fd5b8135818111156109e257600080fd5b8760208285010111156109f457600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114610a2957600080fd5b50565b60008060008060808587031215610a4257600080fd5b8435610a4d81610a07565b93506020850135610a5d81610a07565b9250604085013591506060850135610a7481610a07565b939692955090935050565b60005b83811015610a9a578181015183820152602001610a82565b50506000910152565b60008251610ab5818460208701610a7f565b9190910192915050565b600060208284031215610ad157600080fd5b5051919050565b81810381811115610b12577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b92915050565b600060208284031215610b2a57600080fd5b81516108a381610a07565b600060208284031215610b4757600080fd5b815180151581146108a357600080fd5b6020815260008251806020840152610b76816040850160208701610a7f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea164736f6c6343000811000a","deployedBytecode":"0x60806040526004361061002d5760003560e01c80631626ba7e1461008657806357d5a1d3146100fe57610034565b3661003457005b600061007c6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525062010000939250506101209050565b9050805160208201f35b34801561009257600080fd5b506100c96100a136600461098b565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200160405180910390f35b34801561010a57600080fd5b5061011e610119366004610a2c565b6101a2565b005b606060008373ffffffffffffffffffffffffffffffffffffffff16836040516101499190610aa3565b600060405180830381855af49150503d8060008114610184576040519150601f19603f3d011682016040523d82523d6000602084013e610189565b606091505b50925090508061019b57815160208301fd5b5092915050565b6101aa61077f565b1561023c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f70726570617265537761702063616e206f6e6c792062652063616c6c6564206f60448201527f6e6365000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036103e7576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156102dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103009190610abf565b9050828110156103e55760006103168285610ad8565b905080471015610382576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6e6f7420656e6f7567682045544820746f2077726170000000000000000000006044820152606401610233565b8273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103ca57600080fd5b505af11580156103de573d6000803e3d6000fd5b5050505050505b505b60008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e308773ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610451573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104759190610b18565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa1580156104e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105099190610abf565b905082811015610654576105a48573ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610561573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105859190610b18565b73ffffffffffffffffffffffffffffffffffffffff86169060006107ba565b6106548573ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106169190610b18565b73ffffffffffffffffffffffffffffffffffffffff8616907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6107ba565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa1580156106c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e59190610abf565b905083811015610777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f74726164657220646f6573206e6f74206861766520656e6f7567682073656c6c60448201527f5f746f6b656e00000000000000000000000000000000000000000000000000006064820152608401610233565b505050505050565b6000806107ad60017f7f36ecad6e52bbe2ff70badce94360882c890b7877b16131c08eabfc635c9735610ad8565b8054600190915592915050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529060009061084d90861683610895565b905061088e816040518060400160405280601a81526020017f5361666545524332303a20617070726f76616c206661696c65640000000000008152506108aa565b5050505050565b60606108a383600084610905565b9392505050565b815115806108c75750818060200190518101906108c79190610b35565b8190610900576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102339190610b57565b505050565b606060008473ffffffffffffffffffffffffffffffffffffffff16848460405161092f9190610aa3565b60006040518083038185875af1925050503d806000811461096c576040519150601f19603f3d011682016040523d82523d6000602084013e610971565b606091505b50925090508061098357815160208301fd5b509392505050565b6000806000604084860312156109a057600080fd5b83359250602084013567ffffffffffffffff808211156109bf57600080fd5b818601915086601f8301126109d357600080fd5b8135818111156109e257600080fd5b8760208285010111156109f457600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114610a2957600080fd5b50565b60008060008060808587031215610a4257600080fd5b8435610a4d81610a07565b93506020850135610a5d81610a07565b9250604085013591506060850135610a7481610a07565b939692955090935050565b60005b83811015610a9a578181015183820152602001610a82565b50506000910152565b60008251610ab5818460208701610a7f565b9190910192915050565b600060208284031215610ad157600080fd5b5051919050565b81810381811115610b12577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b92915050565b600060208284031215610b2a57600080fd5b81516108a381610a07565b600060208284031215610b4757600080fd5b815180151581146108a357600080fd5b6020815260008251806020840152610b76816040850160208701610a7f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea164736f6c6343000811000a","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"}],"name":"prepareSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}],"bytecode":"0x608060405234801561001057600080fd5b50610a97806100206000396000f3fe60806040526004361061002d5760003560e01c80631626ba7e1461008657806357d5a1d3146100fe57610034565b3661003457005b600061007c6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525062010000939250506101209050565b9050805160208201f35b34801561009257600080fd5b506100c96100a1366004610873565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200160405180910390f35b34801561010a57600080fd5b5061011e610119366004610914565b6101a2565b005b606060008373ffffffffffffffffffffffffffffffffffffffff1683604051610149919061098b565b600060405180830381855af49150503d8060008114610184576040519150601f19603f3d011682016040523d82523d6000602084013e610189565b606091505b50925090508061019b57815160208301fd5b5092915050565b6101aa61065b565b1561023c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f70726570617265537761702063616e206f6e6c792062652063616c6c6564206f60448201527f6e6365000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036103e7576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156102dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061030091906109a7565b9050828110156103e557600061031682856109c0565b905080471015610382576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6e6f7420656e6f7567682045544820746f2077726170000000000000000000006044820152606401610233565b8273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103ca57600080fd5b505af11580156103de573d6000803e3d6000fd5b5050505050505b505b60008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e308773ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610451573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061047591906109fa565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa1580156104e5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050991906109a7565b905082811015610654576105a48573ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610561573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058591906109fa565b73ffffffffffffffffffffffffffffffffffffffff8616906000610696565b6106548573ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061691906109fa565b73ffffffffffffffffffffffffffffffffffffffff8616907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610696565b5050505050565b60008061068960017f7f36ecad6e52bbe2ff70badce94360882c890b7877b16131c08eabfc635c97356109c0565b8054600190915592915050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052906000906107299086168361076a565b9050610654816040518060400160405280601a81526020017f5361666545524332303a20617070726f76616c206661696c656400000000000081525061077f565b6060610778836000846107c6565b9392505050565b6107888261084c565b81906107c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102339190610a17565b505050565b606060008473ffffffffffffffffffffffffffffffffffffffff1684846040516107f0919061098b565b60006040518083038185875af1925050503d806000811461082d576040519150601f19603f3d011682016040523d82523d6000602084013e610832565b606091505b50925090508061084457815160208301fd5b509392505050565b600081516000148061086d57508180602001905181019061086d9190610a68565b92915050565b60008060006040848603121561088857600080fd5b83359250602084013567ffffffffffffffff808211156108a757600080fd5b818601915086601f8301126108bb57600080fd5b8135818111156108ca57600080fd5b8760208285010111156108dc57600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff8116811461091157600080fd5b50565b6000806000806080858703121561092a57600080fd5b8435610935816108ef565b93506020850135610945816108ef565b925060408501359150606085013561095c816108ef565b939692955090935050565b60005b8381101561098257818101518382015260200161096a565b50506000910152565b6000825161099d818460208701610967565b9190910192915050565b6000602082840312156109b957600080fd5b5051919050565b8181038181111561086d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060208284031215610a0c57600080fd5b8151610778816108ef565b6020815260008251806020840152610a36816040850160208701610967565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600060208284031215610a7a57600080fd5b8151801515811461077857600080fdfea164736f6c6343000811000a","deployedBytecode":"0x60806040526004361061002d5760003560e01c80631626ba7e1461008657806357d5a1d3146100fe57610034565b3661003457005b600061007c6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525062010000939250506101209050565b9050805160208201f35b34801561009257600080fd5b506100c96100a1366004610873565b7f1626ba7e000000000000000000000000000000000000000000000000000000009392505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200160405180910390f35b34801561010a57600080fd5b5061011e610119366004610914565b6101a2565b005b606060008373ffffffffffffffffffffffffffffffffffffffff1683604051610149919061098b565b600060405180830381855af49150503d8060008114610184576040519150601f19603f3d011682016040523d82523d6000602084013e610189565b606091505b50925090508061019b57815160208301fd5b5092915050565b6101aa61065b565b1561023c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f70726570617265537761702063616e206f6e6c792062652063616c6c6564206f60448201527f6e6365000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036103e7576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156102dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061030091906109a7565b9050828110156103e557600061031682856109c0565b905080471015610382576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6e6f7420656e6f7567682045544820746f2077726170000000000000000000006044820152606401610233565b8273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103ca57600080fd5b505af11580156103de573d6000803e3d6000fd5b5050505050505b505b60008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e308773ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610451573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061047591906109fa565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa1580156104e5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050991906109a7565b905082811015610654576105a48573ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610561573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058591906109fa565b73ffffffffffffffffffffffffffffffffffffffff8616906000610696565b6106548573ffffffffffffffffffffffffffffffffffffffff16639b552cc26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061691906109fa565b73ffffffffffffffffffffffffffffffffffffffff8616907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610696565b5050505050565b60008061068960017f7f36ecad6e52bbe2ff70badce94360882c890b7877b16131c08eabfc635c97356109c0565b8054600190915592915050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052906000906107299086168361076a565b9050610654816040518060400160405280601a81526020017f5361666545524332303a20617070726f76616c206661696c656400000000000081525061077f565b6060610778836000846107c6565b9392505050565b6107888261084c565b81906107c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102339190610a17565b505050565b606060008473ffffffffffffffffffffffffffffffffffffffff1684846040516107f0919061098b565b60006040518083038185875af1925050503d806000811461082d576040519150601f19603f3d011682016040523d82523d6000602084013e610832565b606091505b50925090508061084457815160208301fd5b509392505050565b600081516000148061086d57508180602001905181019061086d9190610a68565b92915050565b60008060006040848603121561088857600080fd5b83359250602084013567ffffffffffffffff808211156108a757600080fd5b818601915086601f8301126108bb57600080fd5b8135818111156108ca57600080fd5b8760208285010111156108dc57600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff8116811461091157600080fd5b50565b6000806000806080858703121561092a57600080fd5b8435610935816108ef565b93506020850135610945816108ef565b925060408501359150606085013561095c816108ef565b939692955090935050565b60005b8381101561098257818101518382015260200161096a565b50506000910152565b6000825161099d818460208701610967565b9190910192915050565b6000602082840312156109b957600080fd5b5051919050565b8181038181111561086d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060208284031215610a0c57600080fd5b8151610778816108ef565b6020815260008251806020840152610a36816040850160208701610967565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600060208284031215610a7a57600080fd5b8151801515811461077857600080fdfea164736f6c6343000811000a","devdoc":{"methods":{}},"userdoc":{"methods":{}}} diff --git a/crates/contracts/build.rs b/crates/contracts/build.rs index 7a6e4369bb..dda30d09e8 100644 --- a/crates/contracts/build.rs +++ b/crates/contracts/build.rs @@ -990,8 +990,9 @@ fn main() { generate_contract("CowAmmUniswapV2PriceOracle"); // Support contracts used for trade and token simulations. - generate_contract("Trader"); generate_contract("Solver"); + generate_contract("Spardose"); + generate_contract("Trader"); // Support contracts used for various order simulations. generate_contract("Balances"); diff --git a/crates/contracts/solidity/Makefile b/crates/contracts/solidity/Makefile index 5816391d8d..9402416722 100644 --- a/crates/contracts/solidity/Makefile +++ b/crates/contracts/solidity/Makefile @@ -14,6 +14,7 @@ CONTRACTS := \ Signatures.sol \ SimulateCode.sol \ Solver.sol \ + Spardose.sol \ Swapper.sol \ Trader.sol ARTIFACTS := $(patsubst %.sol,$(ARTIFACTDIR)/%.json,$(CONTRACTS)) diff --git a/crates/contracts/solidity/Solver.sol b/crates/contracts/solidity/Solver.sol index 9833c1e5c1..eece404458 100644 --- a/crates/contracts/solidity/Solver.sol +++ b/crates/contracts/solidity/Solver.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"; import { Trader } from "./Trader.sol"; /// @title A contract for impersonating a solver. This contract @@ -16,7 +17,11 @@ import { Trader } from "./Trader.sol"; contract Solver { using Caller for *; using Math for *; - using SafeERC20 for *; + + struct Mock { + bool enabled; + address spardose; + } uint256 private _simulationOverhead; uint256[] private _queriedBalances; @@ -35,10 +40,10 @@ contract Solver { /// @param tokens - list of tokens used in the trade /// @param receiver - address receiving the bought tokens /// @param settlementCall - the calldata of the `settle()` call - /// @param mockPreconditions - controls whether things like ETH wrapping - /// or setting allowance should be done on behalf of the - /// user to support quote verification even if the user didn't - /// wrap their ETH or set the necessary allowances yet. + /// @param mock - mocking configuration for the simulation; this controls + /// whether things like ETH wrapping, setting allowance and + /// pre-funding should be done on behalf of the user to support + /// quote verification for users who aren't ready to swap. /// /// @return gasUsed - gas used for the `settle()` call /// @return queriedBalances - list of balances stored during the simulation @@ -51,16 +56,16 @@ contract Solver { address[] calldata tokens, address payable receiver, bytes calldata settlementCall, - bool mockPreconditions + Mock memory mock ) external returns ( uint256 gasUsed, uint256[] memory queriedBalances ) { require(msg.sender == address(this), "only simulation logic is allowed to call 'swap' function"); - // Prepare the trade in the context of the trader so we are allowed - // to set approvals and things like that. - if (mockPreconditions) { + if (mock.enabled) { + // Prepare the trade in the context of the trader so we are allowed + // to set approvals and things like that. Trader(trader) .prepareSwap( settlementContract, @@ -68,13 +73,24 @@ contract Solver { sellAmount, nativeToken ); + + // 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. // We allow this call to revert becaues it was either unnecessary in the first place // or failing to send `ETH` to the `receiver` will cause a revert in the settlement // contract. - receiver.call{value: 0}(""); + { + (bool success,) = receiver.call{value: 0}(""); + success; + } // Store pre-settlement balances _storeSettlementBalances(tokens, settlementContract); diff --git a/crates/contracts/solidity/Spardose.sol b/crates/contracts/solidity/Spardose.sol new file mode 100644 index 0000000000..c1fa6167be --- /dev/null +++ b/crates/contracts/solidity/Spardose.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import { IERC20 } from "./interfaces/IERC20.sol"; +import { SafeERC20 } from "./libraries/SafeERC20.sol"; + +/// @title A piggy bank contract (Spardose is piggy bank in German) +/// @notice This contract account is used for pre-funding traders with tokens +/// for quote simulations. A separate contract is used (instead of overriding +/// the balance of the solver or trader directly) in order to interfere as +/// little as possible with the settlement. +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. + /// + /// @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); + } +} diff --git a/crates/contracts/solidity/Trader.sol b/crates/contracts/solidity/Trader.sol index d1354cb982..c9fa5e0fdf 100644 --- a/crates/contracts/solidity/Trader.sol +++ b/crates/contracts/solidity/Trader.sol @@ -99,9 +99,6 @@ contract Trader { IERC20(sellToken).safeApprove(address(settlementContract.vaultRelayer()), 0); IERC20(sellToken).safeApprove(address(settlementContract.vaultRelayer()), type(uint256).max); } - - uint256 availableSellToken = IERC20(sellToken).balanceOf(address(this)); - require(availableSellToken >= sellAmount, "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 785ff3324d..9cc30ef35f 100644 --- a/crates/contracts/solidity/libraries/SafeERC20.sol +++ b/crates/contracts/solidity/libraries/SafeERC20.sol @@ -7,13 +7,24 @@ import { Caller } from "./Caller.sol"; library SafeERC20 { using Caller for *; + function trySafeTransfer(IERC20 self, address target, uint256 amount) internal returns (bool success) { + bytes memory cdata = abi.encodeCall(self.transfer, (target, amount)); + bytes memory rdata; + (success, rdata) = address(self).call(cdata); + return success && check(rdata); + } + 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); - check(rdata, "SafeERC20: approval failed"); + ensure(rdata, "SafeERC20: approval failed"); + } + + function check(bytes memory rdata) internal pure returns (bool ok) { + return rdata.length == 0 || abi.decode(rdata, (bool)); } - function check(bytes memory self, string memory message) internal pure { - require(self.length == 0 || abi.decode(self, (bool)), message); + function ensure(bytes memory rdata, string memory message) internal pure { + require(check(rdata), message); } } diff --git a/crates/contracts/src/lib.rs b/crates/contracts/src/lib.rs index b033656adb..f9aefaca3e 100644 --- a/crates/contracts/src/lib.rs +++ b/crates/contracts/src/lib.rs @@ -114,6 +114,7 @@ pub mod support { Signatures; SimulateCode; Solver; + Spardose; Swapper; Trader; } diff --git a/crates/e2e/tests/e2e/quote_verification.rs b/crates/e2e/tests/e2e/quote_verification.rs index 5e442d2e35..2aafb0e98b 100644 --- a/crates/e2e/tests/e2e/quote_verification.rs +++ b/crates/e2e/tests/e2e/quote_verification.rs @@ -1,7 +1,7 @@ use { bigdecimal::{BigDecimal, Zero}, - e2e::setup::*, - ethcontract::H160, + e2e::{setup::*, tx}, + ethcontract::{H160, U256}, ethrpc::Web3, model::{ order::{BuyTokenDestination, OrderKind, SellTokenSource}, @@ -19,6 +19,12 @@ use { std::{str::FromStr, sync::Arc}, }; +#[tokio::test] +#[ignore] +async fn local_node_standard_verified_quote() { + run_test(standard_verified_quote).await; +} + #[tokio::test] #[ignore] async fn forked_node_bypass_verification_for_rfq_quotes() { @@ -37,6 +43,51 @@ async fn local_node_verified_quote_for_settlement_contract() { run_test(verified_quote_for_settlement_contract).await; } +#[tokio::test] +#[ignore] +async fn local_node_verified_quote_with_simulated_balance() { + run_test(verified_quote_with_simulated_balance).await; +} + +/// Verified quotes work as expected. +async fn standard_verified_quote(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; + + token.mint(trader.address(), to_wei(1)).await; + tx!( + trader.account(), + token.approve(onchain.contracts().allowance, to_wei(1)) + ); + + tracing::info!("Starting services."); + let services = Services::new(&onchain).await; + services.start_protocol(solver).await; + + // quote where the trader has no balances or approval set. + let response = services + .submit_quote(&OrderQuoteRequest { + from: trader.address(), + sell_token: token.address(), + buy_token: onchain.contracts().weth.address(), + side: OrderQuoteSide::Sell { + sell_amount: SellAmount::BeforeFee { + value: to_wei(1).try_into().unwrap(), + }, + }, + ..Default::default() + }) + .await + .unwrap(); + assert!(response.verified); +} + /// The block number from which we will fetch state for the forked tests. const FORK_BLOCK_MAINNET: u64 = 19796077; @@ -208,3 +259,50 @@ async fn verified_quote_for_settlement_contract(web3: Web3) { .unwrap(); assert!(response.verified); } + +/// Test that asserts that we can verify quotes for traders with simulated +/// balances. +async fn verified_quote_with_simulated_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(0)).await; + let [token] = onchain + .deploy_tokens_with_weth_uni_v2_pools(to_wei(1_000), to_wei(1_000)) + .await; + + tracing::info!("Starting services."); + let services = Services::new(&onchain).await; + services + .start_protocol_with_args( + ExtraServiceArgs { + api: vec![format!( + // The OpenZeppelin `ERC20Mintable` token uses a mapping in + // the first (0'th) storage slot for balances. + "--quote-token-balance-overrides={:?}@0", + token.address() + )], + ..Default::default() + }, + solver, + ) + .await; + + // quote where the trader has no balances or approval set. + let response = services + .submit_quote(&OrderQuoteRequest { + from: trader.address(), + sell_token: token.address(), + buy_token: onchain.contracts().weth.address(), + side: OrderQuoteSide::Sell { + sell_amount: SellAmount::BeforeFee { + value: to_wei(1).try_into().unwrap(), + }, + }, + ..Default::default() + }) + .await + .unwrap(); + assert!(response.verified); +} diff --git a/crates/ethrpc/src/extensions.rs b/crates/ethrpc/src/extensions.rs index 78f2d77eea..d57ff77993 100644 --- a/crates/ethrpc/src/extensions.rs +++ b/crates/ethrpc/src/extensions.rs @@ -68,12 +68,12 @@ pub struct StateOverride { /// Fake key-value mapping to override **all** slots in the account storage /// before executing the call. #[serde(skip_serializing_if = "Option::is_none")] - pub state: Option>, + pub state: Option>, /// Fake key-value mapping to override **individual** slots in the account /// storage before executing the call. #[serde(skip_serializing_if = "Option::is_none")] - pub state_diff: Option>, + pub state_diff: Option>, } #[cfg(test)] diff --git a/crates/shared/src/code_simulation.rs b/crates/shared/src/code_simulation.rs index 7035c2dfb6..40a3fb4d82 100644 --- a/crates/shared/src/code_simulation.rs +++ b/crates/shared/src/code_simulation.rs @@ -4,7 +4,7 @@ use { crate::tenderly_api::{SimulationKind, SimulationRequest, StateObject, TenderlyApi}, anyhow::{ensure, Context as _, Result}, contracts::errors::EthcontractErrorType, - ethcontract::{errors::ExecutionError, H256}, + ethcontract::errors::ExecutionError, ethrpc::{ extensions::{EthExt as _, StateOverride, StateOverrides}, Web3, @@ -206,16 +206,7 @@ impl TryFrom for StateObject { Ok(StateObject { balance: value.balance, code: value.code, - storage: value.state_diff.map(|state_diff| { - state_diff - .into_iter() - .map(|(key, uint)| { - let mut value = H256::default(); - uint.to_big_endian(&mut value.0); - (key, value) - }) - .collect() - }), + storage: value.state_diff, }) } } @@ -262,6 +253,7 @@ mod tests { use { super::*, crate::{ethrpc::create_env_test_transport, tenderly_api::TenderlyHttpApi}, + ethcontract::H256, hex_literal::hex, maplit::hashmap, std::time::Duration, @@ -393,7 +385,8 @@ mod tests { hashmap! { addr!("D533a949740bb3306d119CC777fa900bA034cd52") => StateOverride { state_diff: Some(hashmap! { - H256(balance_slot) => 1.into() + H256(balance_slot) => + H256(hex!("0000000000000000000000000000000000000000000000000000000000000001")), }), ..Default::default() }, diff --git a/crates/shared/src/price_estimation/factory.rs b/crates/shared/src/price_estimation/factory.rs index 03b2083264..2d660adf03 100644 --- a/crates/shared/src/price_estimation/factory.rs +++ b/crates/shared/src/price_estimation/factory.rs @@ -113,18 +113,21 @@ impl<'a> PriceEstimatorFactory<'a> { None => Arc::new(web3.clone()), }; - Ok(Some(Arc::new( - TradeVerifier::new( - web3, - simulator, - components.code_fetcher.clone(), - network.block_stream.clone(), - network.settlement, - network.native_token, - args.quote_inaccuracy_limit.clone(), - ) - .await?, - ))) + let balance_overrides = Arc::new(args.quote_token_balance_overrides.clone()); + + let verifier = TradeVerifier::new( + web3, + simulator, + components.code_fetcher.clone(), + network.block_stream.clone(), + network.settlement, + network.native_token, + args.quote_inaccuracy_limit.clone(), + ) + .await? + .with_balance_overrides(balance_overrides); + + Ok(Some(Arc::new(verifier))) } fn native_token_price_estimation_amount(&self) -> Result { diff --git a/crates/shared/src/price_estimation/mod.rs b/crates/shared/src/price_estimation/mod.rs index 9ba6405f9a..607925bc83 100644 --- a/crates/shared/src/price_estimation/mod.rs +++ b/crates/shared/src/price_estimation/mod.rs @@ -1,4 +1,5 @@ use { + self::trade_verifier::balance_overrides::ConfigurationBalanceOverrides, crate::{ arguments::{display_option, display_secret_option, ExternalSolver}, trade_finding::Interaction, @@ -211,6 +212,17 @@ pub struct Arguments { value_parser = humantime::parse_duration, )] 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, } #[derive(clap::Parser)] @@ -290,6 +302,7 @@ impl Display for Arguments { quote_inaccuracy_limit, quote_verification, quote_timeout, + quote_token_balance_overrides, } = self; display_option( @@ -367,6 +380,11 @@ 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 + )?; Ok(()) } diff --git a/crates/shared/src/price_estimation/trade_verifier.rs b/crates/shared/src/price_estimation/trade_verifier.rs index 7107ac5ff0..fed26bb928 100644 --- a/crates/shared/src/price_estimation/trade_verifier.rs +++ b/crates/shared/src/price_estimation/trade_verifier.rs @@ -1,6 +1,11 @@ pub mod balance_overrides; use { + self::balance_overrides::{ + BalanceOverrideRequest, + BalanceOverriding, + ConfigurationBalanceOverrides, + }, super::{Estimate, Verification}, crate::{ code_fetching::CodeFetching, @@ -18,7 +23,7 @@ use { contracts::{ deployed_bytecode, dummy_contract, - support::{AnyoneAuthenticator, Solver, Trader}, + support::{AnyoneAuthenticator, Solver, Spardose, Trader}, GPv2Settlement, WETH9, }, @@ -58,6 +63,7 @@ pub struct TradeVerifier { web3: Web3, simulator: Arc, code_fetcher: Arc, + balance_overrides: Arc, block_stream: CurrentBlockWatcher, settlement: GPv2Settlement, native_token: H160, @@ -67,6 +73,7 @@ pub struct TradeVerifier { impl TradeVerifier { const DEFAULT_GAS: u64 = 8_000_000; + const SPARDOSE: H160 = addr!("0000000000000000000000000000000000020000"); const TRADER_IMPL: H160 = addr!("0000000000000000000000000000000000010000"); pub async fn new( @@ -84,6 +91,7 @@ impl TradeVerifier { Ok(Self { simulator, code_fetcher, + balance_overrides: Arc::new(ConfigurationBalanceOverrides::default()), block_stream, settlement: settlement_contract, native_token, @@ -93,6 +101,11 @@ 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, @@ -153,6 +166,11 @@ impl TradeVerifier { OrderKind::Buy => *out_amount, }; + // Only enable additional mocking (approvals, native token wrapping, + // balance overrides) if the user did not provide pre-interactions. If + // the user did provide pre-interactions, it's reasonable to assume that + // they will set up all the necessary details of the trade. + let mock_enabled = verification.pre_interactions.is_empty(); let simulation = solver .methods() .swap( @@ -164,11 +182,7 @@ impl TradeVerifier { tokens.clone(), verification.receiver, Bytes(settlement.data.unwrap().0), - // only if the user did not provide pre-interactions is it safe - // to set up the trade's pre-conditions on behalf of the user. - // if the user provided pre-interactions it's reasonable to assume - // that they will set up all the necessary details for the trade. - verification.pre_interactions.is_empty(), + (mock_enabled, Self::SPARDOSE), ) .tx; @@ -185,7 +199,7 @@ impl TradeVerifier { }; let overrides = self - .prepare_state_overrides(verification, trade) + .prepare_state_overrides(verification, query, trade) .await .map_err(Error::SimulationFailed)?; @@ -281,6 +295,7 @@ impl TradeVerifier { async fn prepare_state_overrides( &self, verification: &Verification, + query: &PriceQuery, trade: &TradeKind, ) -> Result> { // Set up mocked trader. @@ -308,6 +323,47 @@ impl TradeVerifier { ); } + // Setup the funding contract override. Regardless of whether or not the + // contract has funds, it needs to exist in order to not revert + // simulations (Solidity reverts on attempts to call addresses without + // any code). + overrides.insert( + Self::SPARDOSE, + StateOverride { + code: Some(deployed_bytecode!(Spardose)), + ..Default::default() + }, + ); + + // Provide mocked balances if possible to the spardose to allow it to + // give some balances to the trader in order to verify trades even for + // owners without balances. Note that we use a separate account for + // funding to not interfere with the settlement process. This allows the + // simulation to conditionally transfer the balance only when it is + // safe to mock the trade pre-conditions on behalf of the user and to + // 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, + )?, + }, + }) + { + tracing::debug!(?solver_balance_override, "solver balance override enabled"); + overrides.insert(query.sell_token, solver_balance_override); + } + // Set up mocked solver. let mut solver_override = StateOverride { code: Some(deployed_bytecode!(Solver)), 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 e8992efb6c..65e04f0665 100644 --- a/crates/shared/src/price_estimation/trade_verifier/balance_overrides.rs +++ b/crates/shared/src/price_estimation/trade_verifier/balance_overrides.rs @@ -1,8 +1,13 @@ use { + anyhow::Context as _, ethcontract::{Address, H256, U256}, ethrpc::extensions::StateOverride, maplit::hashmap, - std::collections::HashMap, + std::{ + collections::HashMap, + fmt::{self, Display, Formatter}, + str::FromStr, + }, web3::signing, }; @@ -10,7 +15,7 @@ use { /// /// This allows a wider range of verified quotes to work, even when balances /// are not available for the quoter. -pub trait BalanceOverriding { +pub trait BalanceOverriding: Send + Sync + 'static { fn state_override(&self, request: &BalanceOverrideRequest) -> Option; } @@ -43,13 +48,68 @@ impl BalanceOverriding for ConfigurationBalanceOverrides { fn state_override(&self, request: &BalanceOverrideRequest) -> Option { let strategy = self.0.get(&request.token)?; match strategy { - Strategy::Mapping { slot } => Some(StateOverride { - state_diff: Some(hashmap! { - address_mapping_storage_slot(slot, &request.holder) => request.amount, - }), - ..Default::default() - }), + Strategy::Mapping { slot } => { + let slot = address_mapping_storage_slot(slot, &request.holder); + let value = { + let mut value = H256::default(); + request.amount.to_big_endian(&mut value.0); + value + }; + Some(StateOverride { + state_diff: Some(hashmap! { slot => value }), + ..Default::default() + }) + } + } + } +} + +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}"), + }; + + 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 ConfigurationBalanceOverrides { + 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)) } } @@ -84,7 +144,8 @@ mod tests { }), Some(StateOverride { state_diff: Some(hashmap! { - H256(hex!("fca351f4d96129454cfc8ef7930b638ac71fea35eb69ee3b8d959496beb04a33")) => 0x42_u64.into() + H256(hex!("fca351f4d96129454cfc8ef7930b638ac71fea35eb69ee3b8d959496beb04a33")) => + H256(hex!("0000000000000000000000000000000000000000000000000000000000000042")), }), ..Default::default() }), From a88bfbd4cfcb3981188bcd3090cc7f66607ffdcc Mon Sep 17 00:00:00 2001 From: Nicholas Rodrigues Lordello Date: Fri, 6 Dec 2024 10:02:28 +0100 Subject: [PATCH 3/5] Add A Balance Override Detector (#3148) # Description This PR adds a balance override detector for quote verification. This allows tokens to automatically support balance overrides without manual configurations. # Changes A new (but as of yet) unused component is added that can detect balance override strategies for tokens. The current implementation is quite simple - just try a bunch of different slots and see which one works. For now, the number of slots to try is hard-coded at 25, but this can trivially be changed to be configurable in the future. The component is marked with `#[allow(dead_code)]` as it isn't being used anywhere, In the interest of keeping the PR size down, I will add all of the glue code to make it used in a follow up (which will also test whether or not the detector works as expected). ## How to Test In the meantime, I did some local testing to check that it works with tokens for which I know the mapping slot on Ethereum Mainnet (test not included in the PR): ```rust async fn temporary_test() { let web3 = Arc::new(ethrpc::Web3::new(ethrpc::create_test_transport( "https://eth.llamarpc.com", ))); let detector = Detector::new(web3); let result = detector .detect(addr!("A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48")) .await; println!("{result:?}"); assert!(matches!(result, Ok(Strategy::Mapping { slot }) if slot == U256::from(9_u8))); } ``` This test successfully passes! --- .../trade_verifier/balance_overrides.rs | 63 ++++++----- .../balance_overrides/detector.rs | 102 ++++++++++++++++++ 2 files changed, 140 insertions(+), 25 deletions(-) create mode 100644 crates/shared/src/price_estimation/trade_verifier/balance_overrides/detector.rs 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 65e04f0665..ae7550f9a2 100644 --- a/crates/shared/src/price_estimation/trade_verifier/balance_overrides.rs +++ b/crates/shared/src/price_estimation/trade_verifier/balance_overrides.rs @@ -1,3 +1,5 @@ +mod detector; + use { anyhow::Context as _, ethcontract::{Address, H256, U256}, @@ -33,11 +35,42 @@ pub struct BalanceOverrideRequest { #[derive(Clone, Debug, Default)] pub struct ConfigurationBalanceOverrides(HashMap); +/// Balance override strategy for a token. #[derive(Clone, Debug)] pub enum Strategy { + /// Balance override strategy for tokens whose balances are stored in a + /// direct Solidity mapping from token holder to balance amount in the + /// form `mapping(address holder => uint256 amount)`. + /// + /// The strategy is configured with the storage slot [^1] of the mapping. + /// + /// [^1]: Mapping { slot: U256 }, } +impl Strategy { + /// Computes the storage slot and value to override for a particular token + /// holder and amount. + fn state_override(&self, holder: &Address, amount: &U256) -> (H256, H256) { + match self { + Self::Mapping { slot } => { + let key = { + let mut buf = [0; 64]; + buf[12..32].copy_from_slice(holder.as_fixed_bytes()); + slot.to_big_endian(&mut buf[32..64]); + H256(signing::keccak256(&buf)) + }; + let value = { + let mut buf = [0; 32]; + amount.to_big_endian(&mut buf); + H256(buf) + }; + (key, value) + } + } + } +} + impl ConfigurationBalanceOverrides { pub fn new(config: HashMap) -> Self { Self(config) @@ -47,20 +80,11 @@ impl ConfigurationBalanceOverrides { impl BalanceOverriding for ConfigurationBalanceOverrides { fn state_override(&self, request: &BalanceOverrideRequest) -> Option { let strategy = self.0.get(&request.token)?; - match strategy { - Strategy::Mapping { slot } => { - let slot = address_mapping_storage_slot(slot, &request.holder); - let value = { - let mut value = H256::default(); - request.amount.to_big_endian(&mut value.0); - value - }; - Some(StateOverride { - state_diff: Some(hashmap! { slot => value }), - ..Default::default() - }) - } - } + let (key, value) = strategy.state_override(&request.holder, &request.amount); + Some(StateOverride { + state_diff: Some(hashmap! { key => value }), + ..Default::default() + }) } } @@ -113,17 +137,6 @@ impl FromStr for ConfigurationBalanceOverrides { } } -/// Computes the storage slot where the value is stored for Solidity mappings -/// of the form `mapping(address => ...)`. -/// -/// See . -fn address_mapping_storage_slot(slot: &U256, address: &Address) -> H256 { - let mut buf = [0; 64]; - buf[12..32].copy_from_slice(address.as_fixed_bytes()); - slot.to_big_endian(&mut buf[32..64]); - H256(signing::keccak256(&buf)) -} - #[cfg(test)] mod tests { use {super::*, hex_literal::hex}; 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 new file mode 100644 index 0000000000..0ce48951e3 --- /dev/null +++ b/crates/shared/src/price_estimation/trade_verifier/balance_overrides/detector.rs @@ -0,0 +1,102 @@ +use { + super::Strategy, + crate::code_simulation::{CodeSimulating, SimulationError}, + contracts::{dummy_contract, ERC20}, + ethcontract::{Address, U256}, + ethrpc::extensions::StateOverride, + maplit::hashmap, + std::sync::Arc, + thiserror::Error, + web3::{signing::keccak256, types::CallRequest}, +}; + +/// A heuristic balance override detector based on `eth_call` simulations. +/// +/// This has the exact same node requirements as trade verification. +pub struct Detector { + simulator: Arc, +} + +#[allow(dead_code)] +impl Detector { + /// Number of different slots to try out. + const TRIES: u8 = 25; + + /// Creates a new balance override detector. + pub fn new(simulator: Arc) -> Self { + Self { simulator } + } + + /// Tries to detect the balance override strategy for the specified token. + /// Returns an `Err` if it cannot detect the strategy or an internal + /// simulation fails. + pub async fn detect(&self, token: Address) -> Result { + // This is a pretty unsophisticated strategy where we basically try a + // bunch of different slots and see which one sticks. We try balance + // mappings for the first `TRIES` slots; each with a unique value. + let mut tries = (0..Self::TRIES).map(|i| { + let strategy = Strategy::Mapping { + slot: U256::from(i), + }; + // Use an exact value which isn't too large or too small. This helps + // not have false positives for cases where the token balances in + // some other denomination from the actual token balance (such as + // stETH for example) and not run into issues with overflows. + let amount = U256::from(u64::from_be_bytes([i; 8])); + + (strategy, amount) + }); + + // On a technical note, Ethereum public addresses are, for the most + // part, generated by taking the 20 last bytes of a Keccak-256 hash (for + // things like contract creation, public address derivation from a + // Secp256k1 public key, etc.), so we use one for our heuristics from a + // 32-byte digest with no know pre-image, to prevent any weird + // interactions with the weird tokens of the world. + let holder = { + let mut address = Address::default(); + address.0.copy_from_slice(&keccak256(b"Moo!")[12..]); + address.0[19] = address.0[19].wrapping_sub(1); + address + }; + + let token = dummy_contract!(ERC20, token); + let call = CallRequest { + to: Some(token.address()), + data: token.methods().balance_of(holder).m.tx.data, + ..Default::default() + }; + let overrides = hashmap! { + token.address() => StateOverride { + state_diff: Some( + tries + .clone() + .map(|(strategy, amount)| strategy.state_override(&holder, &amount)) + .collect(), + ), + ..Default::default() + }, + }; + + let output = self.simulator.simulate(call, overrides, None).await?; + let balance = (output.len() == 32) + .then(|| U256::from_big_endian(&output)) + .ok_or(DetectionError::Decode)?; + + let strategy = tries + .find_map(|(strategy, amount)| (amount == balance).then_some(strategy)) + .ok_or(DetectionError::NotFound)?; + Ok(strategy) + } +} + +/// An error detecting the balance override strategy for a token. +#[derive(Debug, Error)] +pub enum DetectionError { + #[error("could not detect a balance override strategy")] + NotFound, + #[error("unable to decode simulation return data")] + Decode, + #[error(transparent)] + Simulation(#[from] SimulationError), +} From d58ffd7200716c3191930d7debf3bcec089ce693 Mon Sep 17 00:00:00 2001 From: Nicholas Rodrigues Lordello Date: Fri, 6 Dec 2024 12:44:36 +0100 Subject: [PATCH 4/5] 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 { From 78a1b81c5da367fddcb1bf27f7cf9d9b3001fa20 Mon Sep 17 00:00:00 2001 From: Martin Magnus Date: Fri, 6 Dec 2024 17:44:38 +0100 Subject: [PATCH 5/5] Verify quotes from zero address (#3150) # Description @nlordell's recent PR stack enabled the use case where a real trader (wallet is connected in the frontend) does not have the required balances by faking balances. But with the new ability to fake balances for many tokens we can even go one step further. # Changes If we know how to fake balances for the given sell token AND no wallet is connected (i.e. `verification.from.is_zero()`) we simply generate a random address and use that as the trader with fake balances. Using a non-zero address is important because many token transfer functions don't like sending tokens to or from the zero address. This should prevent the annoying UX where you sometime see a really good (unverified) price when your wallet is not connected and end up seeing worse (but verified) prices after you connect your wallet. ## How to test added an e2e test which produces a verified quote with `from: H160::zero()` --- crates/e2e/tests/e2e/quote_verification.rs | 18 +++ .../src/price_estimation/trade_verifier.rs | 110 ++++++++++-------- 2 files changed, 78 insertions(+), 50 deletions(-) diff --git a/crates/e2e/tests/e2e/quote_verification.rs b/crates/e2e/tests/e2e/quote_verification.rs index 8af977edcf..149afbfc7d 100644 --- a/crates/e2e/tests/e2e/quote_verification.rs +++ b/crates/e2e/tests/e2e/quote_verification.rs @@ -409,4 +409,22 @@ async fn verified_quote_with_simulated_balance(web3: Web3) { .await .unwrap(); assert!(response.verified); + + // with balance overrides we can even verify quotes for the 0 address + // which is used when no wallet is connected in the frontend + let response = services + .submit_quote(&OrderQuoteRequest { + from: H160::zero(), + sell_token: weth.address(), + buy_token: token.address(), + side: OrderQuoteSide::Sell { + sell_amount: SellAmount::BeforeFee { + value: to_wei(1).try_into().unwrap(), + }, + }, + ..Default::default() + }) + .await + .unwrap(); + assert!(response.verified); } diff --git a/crates/shared/src/price_estimation/trade_verifier.rs b/crates/shared/src/price_estimation/trade_verifier.rs index 8d871f4656..496cecdd4f 100644 --- a/crates/shared/src/price_estimation/trade_verifier.rs +++ b/crates/shared/src/price_estimation/trade_verifier.rs @@ -25,7 +25,6 @@ use { }, ethcontract::{tokens::Tokenize, Bytes, H160, U256}, ethrpc::{block_stream::CurrentBlockWatcher, extensions::StateOverride, Web3}, - maplit::hashmap, model::{ order::{OrderData, OrderKind, BUY_ETH_ADDRESS}, signature::{Signature, SigningScheme}, @@ -102,17 +101,20 @@ impl TradeVerifier { async fn verify_inner( &self, query: &PriceQuery, - verification: &Verification, + mut verification: Verification, trade: &TradeKind, out_amount: &U256, ) -> Result { - if verification.from.is_zero() { - // Don't waste time on common simulations which will always fail. - return Err(anyhow::anyhow!("trader is zero address").into()); - } - let start = std::time::Instant::now(); + // this may change the `verification` parameter (to make more + // quotes verifiable) so we do it as the first thing to ensure + // that all the following code uses the updated value + let overrides = self + .prepare_state_overrides(&mut verification, query, trade) + .await + .map_err(Error::SimulationFailed)?; + // Use `tx_origin` if response indicates that a special address is needed for // the simulation to pass. Otherwise just use the solver address. let solver = trade.tx_origin().unwrap_or(trade.solver()); @@ -132,7 +134,7 @@ impl TradeVerifier { let settlement = encode_settlement( query, - verification, + &verification, trade, &tokens, &clearing_prices, @@ -141,7 +143,7 @@ impl TradeVerifier { &self.domain_separator, )?; - let settlement = add_balance_queries(settlement, query, verification, &solver); + let settlement = add_balance_queries(settlement, query, &verification, &solver); let settlement = self .settlement @@ -191,11 +193,6 @@ impl TradeVerifier { ..Default::default() }; - let overrides = self - .prepare_state_overrides(verification, query, trade) - .await - .map_err(Error::SimulationFailed)?; - let output = self .simulator .simulate(call, overrides, Some(block.number)) @@ -287,17 +284,60 @@ impl TradeVerifier { /// trade. async fn prepare_state_overrides( &self, - verification: &Verification, + verification: &mut Verification, query: &PriceQuery, trade: &TradeKind, ) -> Result> { + let mut overrides = HashMap::with_capacity(6); + + // Provide mocked balances if possible to the spardose to allow it to + // give some balances to the trader in order to verify trades even for + // owners without balances. Note that we use a separate account for + // funding to not interfere with the settlement process. This allows the + // simulation to conditionally transfer the balance only when it is + // safe to mock the trade pre-conditions on behalf of the user and to + // 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, + )?, + }, + }) + .await + { + tracing::trace!(?solver_balance_override, "solver balance override enabled"); + overrides.insert(query.sell_token, solver_balance_override); + + if verification.from.is_zero() { + verification.from = H160::random(); + tracing::debug!( + trader = ?verification.from, + "use random trader address with fake balances" + ); + } + } else if verification.from.is_zero() { + anyhow::bail!("trader is zero address and balances can not be faked"); + } + // Set up mocked trader. - let mut overrides = hashmap! { - verification.from => StateOverride { + overrides.insert( + verification.from, + StateOverride { code: Some(deployed_bytecode!(Trader)), ..Default::default() }, - }; + ); // If the trader is a smart contract we also need to store its implementation // to proxy into it during the simulation. @@ -328,36 +368,6 @@ impl TradeVerifier { }, ); - // Provide mocked balances if possible to the spardose to allow it to - // give some balances to the trader in order to verify trades even for - // owners without balances. Note that we use a separate account for - // funding to not interfere with the settlement process. This allows the - // simulation to conditionally transfer the balance only when it is - // safe to mock the trade pre-conditions on behalf of the user and to - // 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, - )?, - }, - }) - .await - { - tracing::trace!(?solver_balance_override, "solver balance override enabled"); - overrides.insert(query.sell_token, solver_balance_override); - } - // Set up mocked solver. let mut solver_override = StateOverride { code: Some(deployed_bytecode!(Solver)), @@ -408,7 +418,7 @@ impl TradeVerifying for TradeVerifier { ) .context("failed to compute trade out amount")?; match self - .verify_inner(query, verification, &trade, &out_amount) + .verify_inner(query, verification.clone(), &trade, &out_amount) .await { Ok(verified) => Ok(verified), @@ -790,7 +800,7 @@ enum Error { #[cfg(test)] mod tests { - use {super::*, std::str::FromStr}; + use {super::*, maplit::hashmap, std::str::FromStr}; #[test] fn discards_inaccurate_quotes() {