From 394fe4db49ef335bb5be1381b35e5c27bc2ece2c Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 18 Apr 2024 20:31:06 +0700 Subject: [PATCH 001/233] use NFT_MAKER_SWAP_V2 in nft_swap_v2 mod and in spend erc721 test --- mm2src/coins/eth.rs | 3 + mm2src/coins/eth/nft_maker_swap_v2_abi.json | 457 ++++++++++++++++++ mm2src/coins/eth/nft_swap_v2/mod.rs | 10 +- .../tests/docker_tests/docker_tests_common.rs | 56 ++- .../tests/docker_tests/eth_docker_tests.rs | 17 +- 5 files changed, 531 insertions(+), 12 deletions(-) create mode 100644 mm2src/coins/eth/nft_maker_swap_v2_abi.json diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 41291b84fd..91350b72aa 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -143,6 +143,7 @@ const ERC721_ABI: &str = include_str!("eth/erc721_abi.json"); /// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1155.md const ERC1155_ABI: &str = include_str!("eth/erc1155_abi.json"); const NFT_SWAP_CONTRACT_ABI: &str = include_str!("eth/nft_swap_contract_abi.json"); +const NFT_MAKER_SWAP_V2_ABI: &str = include_str!("eth/nft_maker_swap_v2_abi.json"); /// Payment states from etomic swap smart contract: https://github.com/artemii235/etomic-swap/blob/master/contracts/EtomicSwap.sol#L5 pub enum PaymentState { @@ -205,6 +206,7 @@ lazy_static! { pub static ref ERC721_CONTRACT: Contract = Contract::load(ERC721_ABI.as_bytes()).unwrap(); pub static ref ERC1155_CONTRACT: Contract = Contract::load(ERC1155_ABI.as_bytes()).unwrap(); pub static ref NFT_SWAP_CONTRACT: Contract = Contract::load(NFT_SWAP_CONTRACT_ABI.as_bytes()).unwrap(); + pub static ref NFT_MAKER_SWAP_V2: Contract = Contract::load(NFT_MAKER_SWAP_V2_ABI.as_bytes()).unwrap(); } pub type Web3RpcFut = Box> + Send>; @@ -4997,6 +4999,7 @@ impl EthCoin { }; if let Some(receipt) = web3_receipt { + println!("Receipt:\n{:?}", receipt); if receipt.status != Some(1.into()) { return MmError::err(Web3RpcError::Internal(ERRL!( "Tx receipt {:?} status of {} tx {:?} is failed", diff --git a/mm2src/coins/eth/nft_maker_swap_v2_abi.json b/mm2src/coins/eth/nft_maker_swap_v2_abi.json new file mode 100644 index 0000000000..5ad7987f6f --- /dev/null +++ b/mm2src/coins/eth/nft_maker_swap_v2_abi.json @@ -0,0 +1,457 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "MakerPaymentRefundedSecret", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "MakerPaymentRefundedTimelock", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "MakerPaymentSent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "MakerPaymentSpent", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "makerPayments", + "outputs": [ + { + "internalType": "bytes20", + "name": "paymentHash", + "type": "bytes20" + }, + { + "internalType": "uint32", + "name": "paymentLockTime", + "type": "uint32" + }, + { + "internalType": "enum EtomicSwapMakerNftV2.MakerPaymentState", + "name": "state", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "taker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecret", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecretHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "refundErc1155MakerPaymentSecret", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "taker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecretHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecretHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "refundErc1155MakerPaymentTimelock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "taker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecret", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecretHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "refundErc721MakerPaymentSecret", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "taker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecretHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecretHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "refundErc721MakerPaymentTimelock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecretHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecret", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "spendErc1155MakerPayment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecretHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecret", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "spendErc721MakerPayment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index 83488deada..14238867dc 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -15,7 +15,7 @@ use structs::{ExpectedHtlcParams, PaymentType, ValidationParams}; use super::ContractType; use crate::eth::{addr_from_raw_pubkey, decode_contract_call, EthCoin, EthCoinType, MakerPaymentStateV2, SignedEthTx, - TryToAddress, ERC1155_CONTRACT, ERC721_CONTRACT, ETH_GAS, NFT_SWAP_CONTRACT}; + TryToAddress, ERC1155_CONTRACT, ERC721_CONTRACT, ETH_GAS, NFT_MAKER_SWAP_V2}; use crate::{ParseCoinAssocTypes, RefundPaymentArgs, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, TransactionErr, ValidateNftMakerPaymentArgs}; @@ -74,7 +74,7 @@ impl EthCoin { .payment_status_v2( *etomic_swap_contract, Token::FixedBytes(swap_id.clone()), - &NFT_SWAP_CONTRACT, + &NFT_MAKER_SWAP_V2, PaymentType::MakerPayments, ) .await?; @@ -144,7 +144,7 @@ impl EthCoin { let (state, htlc_params) = try_tx_s!( self.status_and_htlc_params_from_tx_data( *etomic_swap_contract, - &NFT_SWAP_CONTRACT, + &NFT_MAKER_SWAP_V2, &decoded, index_bytes, PaymentType::MakerPayments, @@ -262,8 +262,8 @@ impl EthCoin { state: U256, ) -> Result, PrepareTxDataError> { let spend_func = match args.contract_type { - ContractType::Erc1155 => NFT_SWAP_CONTRACT.function("spendErc1155MakerPayment")?, - ContractType::Erc721 => NFT_SWAP_CONTRACT.function("spendErc721MakerPayment")?, + ContractType::Erc1155 => NFT_MAKER_SWAP_V2.function("spendErc1155MakerPayment")?, + ContractType::Erc721 => NFT_MAKER_SWAP_V2.function("spendErc721MakerPayment")?, }; if state != U256::from(MakerPaymentStateV2::PaymentSent as u8) { diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index ac099fcc16..7091b39516 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -89,6 +89,8 @@ pub static mut GETH_ERC721_CONTRACT: H160Eth = H160Eth::zero(); pub static mut GETH_ERC1155_CONTRACT: H160Eth = H160Eth::zero(); /// Nft Swap contract address on Geth dev node pub static mut GETH_NFT_SWAP_CONTRACT: H160Eth = H160Eth::zero(); +/// NFT Maker Swap V2 contract address on Geth dev node +pub static mut GETH_NFT_MAKER_SWAP_V2: H160Eth = H160Eth::zero(); pub static GETH_RPC_URL: &str = "http://127.0.0.1:8545"; pub const UTXO_ASSET_DOCKER_IMAGE: &str = "docker.io/artempikulin/testblockchain"; @@ -114,6 +116,7 @@ pub const WATCHERS_SWAP_CONTRACT_BYTES: &str = "608060405234801561000f575f80fd5b pub const ERC721_TEST_TOKEN_BYTES: &str = "608060405234801562000010575f80fd5b50604051620022ac380380620022ac8339818101604052810190620000369190620001ea565b8181815f9081620000489190620004a4565b5080600190816200005a9190620004a4565b505050505062000588565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c6826200007e565b810181811067ffffffffffffffff82111715620000e857620000e76200008e565b5b80604052505050565b5f620000fc62000065565b90506200010a8282620000bb565b919050565b5f67ffffffffffffffff8211156200012c576200012b6200008e565b5b62000137826200007e565b9050602081019050919050565b5f5b838110156200016357808201518184015260208101905062000146565b5f8484015250505050565b5f620001846200017e846200010f565b620000f1565b905082815260208101848484011115620001a357620001a26200007a565b5b620001b084828562000144565b509392505050565b5f82601f830112620001cf57620001ce62000076565b5b8151620001e18482602086016200016e565b91505092915050565b5f80604083850312156200020357620002026200006e565b5b5f83015167ffffffffffffffff81111562000223576200022262000072565b5b6200023185828601620001b8565b925050602083015167ffffffffffffffff81111562000255576200025462000072565b5b6200026385828601620001b8565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620002bc57607f821691505b602082108103620002d257620002d162000277565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002f9565b620003428683620002f9565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200038c6200038662000380846200035a565b62000363565b6200035a565b9050919050565b5f819050919050565b620003a7836200036c565b620003bf620003b68262000393565b84845462000305565b825550505050565b5f90565b620003d5620003c7565b620003e28184846200039c565b505050565b5b818110156200040957620003fd5f82620003cb565b600181019050620003e8565b5050565b601f82111562000458576200042281620002d8565b6200042d84620002ea565b810160208510156200043d578190505b620004556200044c85620002ea565b830182620003e7565b50505b505050565b5f82821c905092915050565b5f6200047a5f19846008026200045d565b1980831691505092915050565b5f62000494838362000469565b9150826002028217905092915050565b620004af826200026d565b67ffffffffffffffff811115620004cb57620004ca6200008e565b5b620004d78254620002a4565b620004e48282856200040d565b5f60209050601f8311600181146200051a575f841562000505578287015190505b62000511858262000487565b86555062000580565b601f1984166200052a86620002d8565b5f5b8281101562000553578489015182556001820191506020850194506020810190506200052c565b868310156200057357848901516200056f601f89168262000469565b8355505b6001600288020188555050505b505050505050565b611d1680620005965f395ff3fe608060405234801561000f575f80fd5b50600436106100e8575f3560e01c80636352211e1161008a578063a22cb46511610064578063a22cb46514610258578063b88d4fde14610274578063c87b56dd14610290578063e985e9c5146102c0576100e8565b80636352211e146101da57806370a082311461020a57806395d89b411461023a576100e8565b8063095ea7b3116100c6578063095ea7b31461016a57806323b872dd1461018657806340c10f19146101a257806342842e0e146101be576100e8565b806301ffc9a7146100ec57806306fdde031461011c578063081812fc1461013a575b5f80fd5b610106600480360381019061010191906115a7565b6102f0565b60405161011391906115ec565b60405180910390f35b6101246103d1565b604051610131919061168f565b60405180910390f35b610154600480360381019061014f91906116e2565b610460565b604051610161919061174c565b60405180910390f35b610184600480360381019061017f919061178f565b61047b565b005b6101a0600480360381019061019b91906117cd565b610491565b005b6101bc60048036038101906101b7919061178f565b610590565b005b6101d860048036038101906101d391906117cd565b61059e565b005b6101f460048036038101906101ef91906116e2565b6105bd565b604051610201919061174c565b60405180910390f35b610224600480360381019061021f919061181d565b6105ce565b6040516102319190611857565b60405180910390f35b610242610684565b60405161024f919061168f565b60405180910390f35b610272600480360381019061026d919061189a565b610714565b005b61028e60048036038101906102899190611a04565b61072a565b005b6102aa60048036038101906102a591906116e2565b610747565b6040516102b7919061168f565b60405180910390f35b6102da60048036038101906102d59190611a84565b6107ad565b6040516102e791906115ec565b60405180910390f35b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103ba57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103ca57506103c98261083b565b5b9050919050565b60605f80546103df90611aef565b80601f016020809104026020016040519081016040528092919081815260200182805461040b90611aef565b80156104565780601f1061042d57610100808354040283529160200191610456565b820191905f5260205f20905b81548152906001019060200180831161043957829003601f168201915b5050505050905090565b5f61046a826108a4565b506104748261092a565b9050919050565b61048d8282610488610963565b61096a565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610501575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016104f8919061174c565b60405180910390fd5b5f610514838361050f610963565b61097c565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461058a578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161058193929190611b1f565b60405180910390fd5b50505050565b61059a8282610b87565b5050565b6105b883838360405180602001604052805f81525061072a565b505050565b5f6105c7826108a4565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361063f575f6040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401610636919061174c565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b60606001805461069390611aef565b80601f01602080910402602001604051908101604052809291908181526020018280546106bf90611aef565b801561070a5780601f106106e15761010080835404028352916020019161070a565b820191905f5260205f20905b8154815290600101906020018083116106ed57829003601f168201915b5050505050905090565b61072661071f610963565b8383610c7a565b5050565b610735848484610491565b61074184848484610de3565b50505050565b6060610752826108a4565b505f61075c610f95565b90505f81511161077a5760405180602001604052805f8152506107a5565b8061078484610fab565b604051602001610795929190611b8e565b6040516020818303038152906040525b915050919050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f806108af83611075565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361092157826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016109189190611857565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b61097783838360016110ae565b505050565b5f8061098784611075565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146109c8576109c781848661126d565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a5357610a075f855f806110ae565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610ad257600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610bf7575f6040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610bee919061174c565b60405180910390fd5b5f610c0383835f61097c565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c75575f6040517f73c6ac6e000000000000000000000000000000000000000000000000000000008152600401610c6c919061174c565b60405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610cea57816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401610ce1919061174c565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610dd691906115ec565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b1115610f8f578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02610e26610963565b8685856040518563ffffffff1660e01b8152600401610e489493929190611c03565b6020604051808303815f875af1925050508015610e8357506040513d601f19601f82011682018060405250810190610e809190611c61565b60015b610f04573d805f8114610eb1576040519150601f19603f3d011682016040523d82523d5f602084013e610eb6565b606091505b505f815103610efc57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610ef3919061174c565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614610f8d57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610f84919061174c565b60405180910390fd5b505b50505050565b606060405180602001604052805f815250905090565b60605f6001610fb984611330565b0190505f8167ffffffffffffffff811115610fd757610fd66118e0565b5b6040519080825280601f01601f1916602001820160405280156110095781602001600182028036833780820191505090505b5090505f82602001820190505b60011561106a578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161105f5761105e611c8c565b5b0494505f8503611016575b819350505050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b80806110e657505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611218575f6110f5846108a4565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561115f57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611172575061117081846107ad565b155b156111b457826040517fa9fbf51f0000000000000000000000000000000000000000000000000000000081526004016111ab919061174c565b60405180910390fd5b811561121657838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b611278838383611481565b61132b575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036112ec57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016112e39190611857565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401611322929190611cb9565b60405180910390fd5b505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061138c577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161138257611381611c8c565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106113c9576d04ee2d6d415b85acef810000000083816113bf576113be611c8c565b5b0492506020810190505b662386f26fc1000083106113f857662386f26fc1000083816113ee576113ed611c8c565b5b0492506010810190505b6305f5e1008310611421576305f5e100838161141757611416611c8c565b5b0492506008810190505b612710831061144657612710838161143c5761143b611c8c565b5b0492506004810190505b60648310611469576064838161145f5761145e611c8c565b5b0492506002810190505b600a8310611478576001810190505b80915050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561153857508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806114f957506114f884846107ad565b5b8061153757508273ffffffffffffffffffffffffffffffffffffffff1661151f8361092a565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61158681611552565b8114611590575f80fd5b50565b5f813590506115a18161157d565b92915050565b5f602082840312156115bc576115bb61154a565b5b5f6115c984828501611593565b91505092915050565b5f8115159050919050565b6115e6816115d2565b82525050565b5f6020820190506115ff5f8301846115dd565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561163c578082015181840152602081019050611621565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61166182611605565b61166b818561160f565b935061167b81856020860161161f565b61168481611647565b840191505092915050565b5f6020820190508181035f8301526116a78184611657565b905092915050565b5f819050919050565b6116c1816116af565b81146116cb575f80fd5b50565b5f813590506116dc816116b8565b92915050565b5f602082840312156116f7576116f661154a565b5b5f611704848285016116ce565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6117368261170d565b9050919050565b6117468161172c565b82525050565b5f60208201905061175f5f83018461173d565b92915050565b61176e8161172c565b8114611778575f80fd5b50565b5f8135905061178981611765565b92915050565b5f80604083850312156117a5576117a461154a565b5b5f6117b28582860161177b565b92505060206117c3858286016116ce565b9150509250929050565b5f805f606084860312156117e4576117e361154a565b5b5f6117f18682870161177b565b93505060206118028682870161177b565b9250506040611813868287016116ce565b9150509250925092565b5f602082840312156118325761183161154a565b5b5f61183f8482850161177b565b91505092915050565b611851816116af565b82525050565b5f60208201905061186a5f830184611848565b92915050565b611879816115d2565b8114611883575f80fd5b50565b5f8135905061189481611870565b92915050565b5f80604083850312156118b0576118af61154a565b5b5f6118bd8582860161177b565b92505060206118ce85828601611886565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61191682611647565b810181811067ffffffffffffffff82111715611935576119346118e0565b5b80604052505050565b5f611947611541565b9050611953828261190d565b919050565b5f67ffffffffffffffff821115611972576119716118e0565b5b61197b82611647565b9050602081019050919050565b828183375f83830152505050565b5f6119a86119a384611958565b61193e565b9050828152602081018484840111156119c4576119c36118dc565b5b6119cf848285611988565b509392505050565b5f82601f8301126119eb576119ea6118d8565b5b81356119fb848260208601611996565b91505092915050565b5f805f8060808587031215611a1c57611a1b61154a565b5b5f611a298782880161177b565b9450506020611a3a8782880161177b565b9350506040611a4b878288016116ce565b925050606085013567ffffffffffffffff811115611a6c57611a6b61154e565b5b611a78878288016119d7565b91505092959194509250565b5f8060408385031215611a9a57611a9961154a565b5b5f611aa78582860161177b565b9250506020611ab88582860161177b565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611b0657607f821691505b602082108103611b1957611b18611ac2565b5b50919050565b5f606082019050611b325f83018661173d565b611b3f6020830185611848565b611b4c604083018461173d565b949350505050565b5f81905092915050565b5f611b6882611605565b611b728185611b54565b9350611b8281856020860161161f565b80840191505092915050565b5f611b998285611b5e565b9150611ba58284611b5e565b91508190509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f611bd582611bb1565b611bdf8185611bbb565b9350611bef81856020860161161f565b611bf881611647565b840191505092915050565b5f608082019050611c165f83018761173d565b611c23602083018661173d565b611c306040830185611848565b8181036060830152611c428184611bcb565b905095945050505050565b5f81519050611c5b8161157d565b92915050565b5f60208284031215611c7657611c7561154a565b5b5f611c8384828501611c4d565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f604082019050611ccc5f83018561173d565b611cd96020830184611848565b939250505056fea26469706673582212207439b47c2a9a1624955997732075917bbf1da26949d000c778f561eb5687576164736f6c63430008180033"; pub const ERC1155_TEST_TOKEN_BYTES: &str = "608060405234801562000010575f80fd5b50604051620024eb380380620024eb8339818101604052810190620000369190620001ea565b8062000048816200005060201b60201c565b505062000554565b806002908162000061919062000470565b5050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c6826200007e565b810181811067ffffffffffffffff82111715620000e857620000e76200008e565b5b80604052505050565b5f620000fc62000065565b90506200010a8282620000bb565b919050565b5f67ffffffffffffffff8211156200012c576200012b6200008e565b5b62000137826200007e565b9050602081019050919050565b5f5b838110156200016357808201518184015260208101905062000146565b5f8484015250505050565b5f620001846200017e846200010f565b620000f1565b905082815260208101848484011115620001a357620001a26200007a565b5b620001b084828562000144565b509392505050565b5f82601f830112620001cf57620001ce62000076565b5b8151620001e18482602086016200016e565b91505092915050565b5f602082840312156200020257620002016200006e565b5b5f82015167ffffffffffffffff81111562000222576200022162000072565b5b6200023084828501620001b8565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200028857607f821691505b6020821081036200029e576200029d62000243565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002c5565b6200030e8683620002c5565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f62000358620003526200034c8462000326565b6200032f565b62000326565b9050919050565b5f819050919050565b620003738362000338565b6200038b62000382826200035f565b848454620002d1565b825550505050565b5f90565b620003a162000393565b620003ae81848462000368565b505050565b5b81811015620003d557620003c95f8262000397565b600181019050620003b4565b5050565b601f8211156200042457620003ee81620002a4565b620003f984620002b6565b8101602085101562000409578190505b620004216200041885620002b6565b830182620003b3565b50505b505050565b5f82821c905092915050565b5f620004465f198460080262000429565b1980831691505092915050565b5f62000460838362000435565b9150826002028217905092915050565b6200047b8262000239565b67ffffffffffffffff8111156200049757620004966200008e565b5b620004a3825462000270565b620004b0828285620003d9565b5f60209050601f831160018114620004e6575f8415620004d1578287015190505b620004dd858262000453565b8655506200054c565b601f198416620004f686620002a4565b5f5b828110156200051f57848901518255600182019150602085019450602081019050620004f8565b868310156200053f57848901516200053b601f89168262000435565b8355505b6001600288020188555050505b505050505050565b611f8980620005625f395ff3fe608060405234801561000f575f80fd5b5060043610610090575f3560e01c80634e1273f4116100645780634e1273f414610140578063731133e914610170578063a22cb4651461018c578063e985e9c5146101a8578063f242432a146101d857610090565b8062fdd58e1461009457806301ffc9a7146100c45780630e89341c146100f45780632eb2c2d614610124575b5f80fd5b6100ae60048036038101906100a991906113bd565b6101f4565b6040516100bb919061140a565b60405180910390f35b6100de60048036038101906100d99190611478565b610249565b6040516100eb91906114bd565b60405180910390f35b61010e600480360381019061010991906114d6565b61032a565b60405161011b919061158b565b60405180910390f35b61013e6004803603810190610139919061179b565b6103bc565b005b61015a60048036038101906101559190611926565b610463565b6040516101679190611a53565b60405180910390f35b61018a60048036038101906101859190611a73565b61056a565b005b6101a660048036038101906101a19190611b1d565b61057c565b005b6101c260048036038101906101bd9190611b5b565b610592565b6040516101cf91906114bd565b60405180910390f35b6101f260048036038101906101ed9190611b99565b610620565b005b5f805f8381526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f7fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061031357507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103235750610322826106c7565b5b9050919050565b60606002805461033990611c59565b80601f016020809104026020016040519081016040528092919081815260200182805461036590611c59565b80156103b05780601f10610387576101008083540402835291602001916103b0565b820191905f5260205f20905b81548152906001019060200180831161039357829003601f168201915b50505050509050919050565b5f6103c5610730565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561040a57506104088682610592565b155b1561044e5780866040517fe237d922000000000000000000000000000000000000000000000000000000008152600401610445929190611c98565b60405180910390fd5b61045b8686868686610737565b505050505050565b606081518351146104af57815183516040517f5b0599910000000000000000000000000000000000000000000000000000000081526004016104a6929190611cbf565b60405180910390fd5b5f835167ffffffffffffffff8111156104cb576104ca6115af565b5b6040519080825280602002602001820160405280156104f95781602001602082028036833780820191505090505b5090505f5b845181101561055f5761053561051d828761082b90919063ffffffff16565b610530838761083e90919063ffffffff16565b6101f4565b82828151811061054857610547611ce6565b5b6020026020010181815250508060010190506104fe565b508091505092915050565b61057684848484610851565b50505050565b61058e610587610730565b83836108e6565b5050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f610629610730565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561066e575061066c8682610592565b155b156106b25780866040517fe237d9220000000000000000000000000000000000000000000000000000000081526004016106a9929190611c98565b60405180910390fd5b6106bf8686868686610a4f565b505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036107a7575f6040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161079e9190611d13565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610817575f6040517f01a8351400000000000000000000000000000000000000000000000000000000815260040161080e9190611d13565b60405180910390fd5b6108248585858585610b55565b5050505050565b5f60208202602084010151905092915050565b5f60208202602084010151905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036108c1575f6040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016108b89190611d13565b60405180910390fd5b5f806108cd8585610c01565b915091506108de5f87848487610b55565b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610956575f6040517fced3e10000000000000000000000000000000000000000000000000000000000815260040161094d9190611d13565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610a4291906114bd565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610abf575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401610ab69190611d13565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610b2f575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401610b269190611d13565b60405180910390fd5b5f80610b3b8585610c01565b91509150610b4c8787848487610b55565b50505050505050565b610b6185858585610c31565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610bfa575f610b9d610730565b90506001845103610be9575f610bbc5f8661083e90919063ffffffff16565b90505f610bd25f8661083e90919063ffffffff16565b9050610be2838989858589610fc1565b5050610bf8565b610bf7818787878787611170565b5b505b5050505050565b60608060405191506001825283602083015260408201905060018152826020820152604081016040529250929050565b8051825114610c7b57815181516040517f5b059991000000000000000000000000000000000000000000000000000000008152600401610c72929190611cbf565b60405180910390fd5b5f610c84610730565b90505f5b8351811015610e80575f610ca5828661083e90919063ffffffff16565b90505f610cbb838661083e90919063ffffffff16565b90505f73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614610dde575f805f8481526020019081526020015f205f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015610d8a57888183856040517f03dee4c5000000000000000000000000000000000000000000000000000000008152600401610d819493929190611d2c565b60405180910390fd5b8181035f808581526020019081526020015f205f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610e7357805f808481526020019081526020015f205f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610e6b9190611d9c565b925050819055505b5050806001019050610c88565b506001835103610f3b575f610e9e5f8561083e90919063ffffffff16565b90505f610eb45f8561083e90919063ffffffff16565b90508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051610f2c929190611cbf565b60405180910390a45050610fba565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051610fb1929190611dcf565b60405180910390a45b5050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115611168578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b8152600401611021959493929190611e56565b6020604051808303815f875af192505050801561105c57506040513d601f19601f820116820180604052508101906110599190611ec2565b60015b6110dd573d805f811461108a576040519150601f19603f3d011682016040523d82523d5f602084013e61108f565b606091505b505f8151036110d557846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016110cc9190611d13565b60405180910390fd5b805181602001fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461116657846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161115d9190611d13565b60405180910390fd5b505b505050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115611317578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b81526004016111d0959493929190611eed565b6020604051808303815f875af192505050801561120b57506040513d601f19601f820116820180604052508101906112089190611ec2565b60015b61128c573d805f8114611239576040519150601f19603f3d011682016040523d82523d5f602084013e61123e565b606091505b505f81510361128457846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161127b9190611d13565b60405180910390fd5b805181602001fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461131557846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161130c9190611d13565b60405180910390fd5b505b505050505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61135982611330565b9050919050565b6113698161134f565b8114611373575f80fd5b50565b5f8135905061138481611360565b92915050565b5f819050919050565b61139c8161138a565b81146113a6575f80fd5b50565b5f813590506113b781611393565b92915050565b5f80604083850312156113d3576113d2611328565b5b5f6113e085828601611376565b92505060206113f1858286016113a9565b9150509250929050565b6114048161138a565b82525050565b5f60208201905061141d5f8301846113fb565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61145781611423565b8114611461575f80fd5b50565b5f813590506114728161144e565b92915050565b5f6020828403121561148d5761148c611328565b5b5f61149a84828501611464565b91505092915050565b5f8115159050919050565b6114b7816114a3565b82525050565b5f6020820190506114d05f8301846114ae565b92915050565b5f602082840312156114eb576114ea611328565b5b5f6114f8848285016113a9565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561153857808201518184015260208101905061151d565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61155d82611501565b611567818561150b565b935061157781856020860161151b565b61158081611543565b840191505092915050565b5f6020820190508181035f8301526115a38184611553565b905092915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6115e582611543565b810181811067ffffffffffffffff82111715611604576116036115af565b5b80604052505050565b5f61161661131f565b905061162282826115dc565b919050565b5f67ffffffffffffffff821115611641576116406115af565b5b602082029050602081019050919050565b5f80fd5b5f61166861166384611627565b61160d565b9050808382526020820190506020840283018581111561168b5761168a611652565b5b835b818110156116b457806116a088826113a9565b84526020840193505060208101905061168d565b5050509392505050565b5f82601f8301126116d2576116d16115ab565b5b81356116e2848260208601611656565b91505092915050565b5f80fd5b5f67ffffffffffffffff821115611709576117086115af565b5b61171282611543565b9050602081019050919050565b828183375f83830152505050565b5f61173f61173a846116ef565b61160d565b90508281526020810184848401111561175b5761175a6116eb565b5b61176684828561171f565b509392505050565b5f82601f830112611782576117816115ab565b5b813561179284826020860161172d565b91505092915050565b5f805f805f60a086880312156117b4576117b3611328565b5b5f6117c188828901611376565b95505060206117d288828901611376565b945050604086013567ffffffffffffffff8111156117f3576117f261132c565b5b6117ff888289016116be565b935050606086013567ffffffffffffffff8111156118205761181f61132c565b5b61182c888289016116be565b925050608086013567ffffffffffffffff81111561184d5761184c61132c565b5b6118598882890161176e565b9150509295509295909350565b5f67ffffffffffffffff8211156118805761187f6115af565b5b602082029050602081019050919050565b5f6118a361189e84611866565b61160d565b905080838252602082019050602084028301858111156118c6576118c5611652565b5b835b818110156118ef57806118db8882611376565b8452602084019350506020810190506118c8565b5050509392505050565b5f82601f83011261190d5761190c6115ab565b5b813561191d848260208601611891565b91505092915050565b5f806040838503121561193c5761193b611328565b5b5f83013567ffffffffffffffff8111156119595761195861132c565b5b611965858286016118f9565b925050602083013567ffffffffffffffff8111156119865761198561132c565b5b611992858286016116be565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6119ce8161138a565b82525050565b5f6119df83836119c5565b60208301905092915050565b5f602082019050919050565b5f611a018261199c565b611a0b81856119a6565b9350611a16836119b6565b805f5b83811015611a46578151611a2d88826119d4565b9750611a38836119eb565b925050600181019050611a19565b5085935050505092915050565b5f6020820190508181035f830152611a6b81846119f7565b905092915050565b5f805f8060808587031215611a8b57611a8a611328565b5b5f611a9887828801611376565b9450506020611aa9878288016113a9565b9350506040611aba878288016113a9565b925050606085013567ffffffffffffffff811115611adb57611ada61132c565b5b611ae78782880161176e565b91505092959194509250565b611afc816114a3565b8114611b06575f80fd5b50565b5f81359050611b1781611af3565b92915050565b5f8060408385031215611b3357611b32611328565b5b5f611b4085828601611376565b9250506020611b5185828601611b09565b9150509250929050565b5f8060408385031215611b7157611b70611328565b5b5f611b7e85828601611376565b9250506020611b8f85828601611376565b9150509250929050565b5f805f805f60a08688031215611bb257611bb1611328565b5b5f611bbf88828901611376565b9550506020611bd088828901611376565b9450506040611be1888289016113a9565b9350506060611bf2888289016113a9565b925050608086013567ffffffffffffffff811115611c1357611c1261132c565b5b611c1f8882890161176e565b9150509295509295909350565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611c7057607f821691505b602082108103611c8357611c82611c2c565b5b50919050565b611c928161134f565b82525050565b5f604082019050611cab5f830185611c89565b611cb86020830184611c89565b9392505050565b5f604082019050611cd25f8301856113fb565b611cdf60208301846113fb565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f602082019050611d265f830184611c89565b92915050565b5f608082019050611d3f5f830187611c89565b611d4c60208301866113fb565b611d5960408301856113fb565b611d6660608301846113fb565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611da68261138a565b9150611db18361138a565b9250828201905080821115611dc957611dc8611d6f565b5b92915050565b5f6040820190508181035f830152611de781856119f7565b90508181036020830152611dfb81846119f7565b90509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f611e2882611e04565b611e328185611e0e565b9350611e4281856020860161151b565b611e4b81611543565b840191505092915050565b5f60a082019050611e695f830188611c89565b611e766020830187611c89565b611e8360408301866113fb565b611e9060608301856113fb565b8181036080830152611ea28184611e1e565b90509695505050505050565b5f81519050611ebc8161144e565b92915050565b5f60208284031215611ed757611ed6611328565b5b5f611ee484828501611eae565b91505092915050565b5f60a082019050611f005f830188611c89565b611f0d6020830187611c89565b8181036040830152611f1f81866119f7565b90508181036060830152611f3381856119f7565b90508181036080830152611f478184611e1e565b9050969550505050505056fea26469706673582212203835581c6344b12728c44fa4d9e912cd60e64012c1b772bb703d1c36825c16fd64736f6c63430008180033"; pub const NFT_SWAP_CONTRACT_BYTES: &str = "60a060405234801562000010575f80fd5b50604051620055a2380380620055a2833981810160405281019062000036919062000147565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200009e90620001fb565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506200021b565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200011182620000e6565b9050919050565b620001238162000105565b81146200012e575f80fd5b50565b5f81519050620001418162000118565b92915050565b5f602082840312156200015f576200015e620000e2565b5b5f6200016e8482850162000131565b91505092915050565b5f82825260208201905092915050565b7f66656541646472657373206d757374206e6f74206265207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f620001e360238362000177565b9150620001f08262000187565b604082019050919050565b5f6020820190508181035f8301526200021481620001d5565b9050919050565b608051615360620002425f395f8181612aef01528181612b8a0152612f4801526153605ff3fe608060405260043610610113575f3560e01c80639b4603f21161009f578063cc90c19911610063578063cc90c1991461038e578063d6a71eb4146103b6578063e06cf966146103de578063efccb9eb14610408578063f23a6e611461044657610113565b80639b4603f2146102be578063b27e46fb146102da578063bc197c8114610302578063c8d9009b1461033e578063c92cd12d1461036657610113565b8063150b7a02116100e6578063150b7a02146101cb5780633e6af5f21461020757806346b95ac71461022f57806365e266171461026e5780636e6bf6d21461029657610113565b806301ffc9a71461011757806305ec158d146101535780630f235fce1461017b578063146e5b24146101a3575b5f80fd5b348015610122575f80fd5b5061013d6004803603810190610138919061386f565b610482565b60405161014a91906138b4565b60405180910390f35b34801561015e575f80fd5b506101796004803603810190610174919061398d565b610563565b005b348015610186575f80fd5b506101a1600480360381019061019c9190613a2a565b610823565b005b3480156101ae575f80fd5b506101c960048036038101906101c49190613ab3565b610add565b005b3480156101d6575f80fd5b506101f160048036038101906101ec9190613bb1565b610cc3565b6040516101fe9190613c44565b60405180910390f35b348015610212575f80fd5b5061022d60048036038101906102289190613ab3565b611112565b005b34801561023a575f80fd5b5061025560048036038101906102509190613c5d565b611423565b6040516102659493929190613d53565b60405180910390f35b348015610279575f80fd5b50610294600480360381019061028f9190613ab3565b611485565b005b3480156102a1575f80fd5b506102bc60048036038101906102b79190613a2a565b6118e9565b005b6102d860048036038101906102d39190613dc0565b611ba4565b005b3480156102e5575f80fd5b5061030060048036038101906102fb919061398d565b611eda565b005b34801561030d575f80fd5b5061032860048036038101906103239190613eb2565b612199565b6040516103359190613c44565b60405180910390f35b348015610349575f80fd5b50610364600480360381019061035f9190613a2a565b6121d5565b005b348015610371575f80fd5b5061038c6004803603810190610387919061398d565b6124fe565b005b348015610399575f80fd5b506103b460048036038101906103af9190613ab3565b61282c565b005b3480156103c1575f80fd5b506103dc60048036038101906103d79190613f89565b612bdc565b005b3480156103e9575f80fd5b506103f2612f46565b6040516103ff919061405c565b60405180910390f35b348015610413575f80fd5b5061042e60048036038101906104299190613c5d565b612f6a565b60405161043d939291906140bb565b60405180910390f35b348015610451575f80fd5b5061046c600480360381019061046791906140f0565b612fb6565b6040516104799190613c44565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061054c57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061055c575061055b8261344a565b5b9050919050565b6001600381111561057757610576613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff1660038111156105a9576105a8613ce0565b5b146105e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e090614206565b60405180910390fd5b5f600387336002896040516020016106019190614244565b60405160208183030381529060405260405161061d91906142ca565b602060405180830381855afa158015610638573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065b91906142f4565b888888886040516020016106759796959493929190614384565b60405160208183030381529060405260405161069191906142ca565b602060405180830381855afa1580156106ac573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610736576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072d9061444e565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561076c5761076b613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd73886040516107a0919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016107eb94939291906144d6565b5f604051808303815f87803b158015610802575f80fd5b505af1158015610814573d5f803e3d5ffd5b50505050505050505050505050565b6001600381111561083757610836613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561086957610868613ce0565b5b146108a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a090614206565b60405180910390fd5b5f60038633878787876040516020016108c79695949392919061452c565b6040516020818303038152906040526040516108e391906142ca565b602060405180830381855afa1580156108fe573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097f9061444e565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156109f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ea9061460b565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610a2957610a28613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907287604051610a5d919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610aa693929190614629565b5f604051808303815f87803b158015610abd575f80fd5b505af1158015610acf573d5f803e3d5ffd5b505050505050505050505050565b60016004811115610af157610af0613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115610b2457610b23613ce0565b5b14610b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5b90614206565b60405180910390fd5b5f600387878733888888604051602001610b84979695949392919061465e565b604051602081830303815290604052604051610ba091906142ca565b602060405180830381855afa158015610bbb573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610c46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3d9061444e565b60405180910390fd5b600260015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610c7d57610c7c613ce0565b5b02179055507f9c45e43e2ef051f70491ffd5221bf02ab37e1324128714ef9610df5f24fc9fb588604051610cb1919061447b565b60405180910390a15050505050505050565b5f808383810190610cd49190614807565b90505f6003811115610ce957610ce8613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff166003811115610d1e57610d1d613ce0565b5b14610d5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d55906148a2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603610dd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc79061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610e42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3990614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610eb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eab90614a00565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610f22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1990614a68565b60405180910390fd5b610f2f81602001516134b3565b15610f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6690614ad0565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610f9d9695949392919061452c565b604051602081830303815290604052604051610fb991906142ca565b602060405180830381855afa158015610fd4573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561102457611023613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156110bb576110ba613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f01516040516110f5919061447b565b60405180910390a163150b7a0260e01b9250505095945050505050565b6001600481111561112657611125613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561115957611158613ce0565b5b14611199576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119090614206565b60405180910390fd5b5f6003878787336002896040516020016111b39190614244565b6040516020818303038152906040526040516111cf91906142ca565b602060405180830381855afa1580156111ea573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061120d91906142f4565b8888604051602001611225979695949392919061465e565b60405160208183030381529060405260405161124191906142ca565b602060405180830381855afa15801561125c573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146112e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112de9061444e565b60405180910390fd5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff0219169083600481111561131e5761131d613ce0565b5b02179055507f45169a52eef651b20a81474b50b8a5d83225225fcd097ef3cf7952d9ab304f278885604051611354929190614aee565b60405180910390a15f86886113699190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113e7573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156113e1573d5f803e3d5ffd5b50611418565b5f83905061141633838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b6001602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900463ffffffff1690805f01601c9054906101000a900460ff16905084565b6001600481111561149957611498613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff1660048111156114cc576114cb613ce0565b5b148061151c5750600260048111156114e7576114e6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561151a57611519613ce0565b5b145b61155b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155290614be5565b60405180910390fd5b5f60038787873388888860405160200161157b979695949392919061465e565b60405160208183030381529060405260405161159791906142ca565b602060405180830381855afa1580156115b2573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461163d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116349061444e565b60405180910390fd5b6002600481111561165157611650613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561168457611683613ce0565b5b036116f65760015f8981526020019081526020015f205f0160189054906101000a900463ffffffff1663ffffffff164210156116f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ec9061460b565b60405180910390fd5b5b6001600481111561170a57611709613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561173d5761173c613ce0565b5b036117af5760015f8981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156117ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a590614c73565b60405180910390fd5b5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156117e6576117e5613ce0565b5b02179055507fbdd7a4be6d82798a500b59077706b12d3f45acf5504828919f92501307b2b9538860405161181a919061447b565b60405180910390a15f868861182f9190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118ad573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156118a7573d5f803e3d5ffd5b506118de565b5f8390506118dc33838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b600160038111156118fd576118fc613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561192f5761192e613ce0565b5b1461196f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196690614206565b60405180910390fd5b5f600386336002886040516020016119879190614244565b6040516020818303038152906040526040516119a391906142ca565b602060405180830381855afa1580156119be573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906119e191906142f4565b8787876040516020016119f99695949392919061452c565b604051602081830303815290604052604051611a1591906142ca565b602060405180830381855afa158015611a30573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611aba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab19061444e565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115611af057611aef613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051611b24919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401611b6d93929190614629565b5f604051808303815f87803b158015611b84575f80fd5b505af1158015611b96573d5f803e3d5ffd5b505050505050505050505050565b5f6004811115611bb757611bb6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115611bea57611be9613ce0565b5b14611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2190614d01565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611c98576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8f90614d8f565b60405180910390fd5b5f3411611cda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd190614e1d565b60405180910390fd5b853411611d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1390614eab565b60405180910390fd5b5f60038734611d2b9190614ec9565b88883389895f604051602001611d47979695949392919061465e565b604051602081830303815290604052604051611d6391906142ca565b602060405180830381855afa158015611d7e573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115611dd657611dd5613ce0565b5b81525060015f8a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115611e9157611e90613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd93588604051611ec8919061447b565b60405180910390a15050505050505050565b60016003811115611eee57611eed613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115611f2057611f1f613ce0565b5b14611f60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5790614206565b60405180910390fd5b5f600387338888888888604051602001611f809796959493929190614384565b604051602081830303815290604052604051611f9c91906142ca565b602060405180830381855afa158015611fb7573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612041576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120389061444e565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156120ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a39061460b565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156120e2576120e1613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907288604051612116919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161216194939291906144d6565b5f604051808303815f87803b158015612178575f80fd5b505af115801561218a573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121cc90614f46565b60405180910390fd5b600160038111156121e9576121e8613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561221b5761221a613ce0565b5b1461225b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161225290614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c090614fae565b60405180910390fd5b5f60033387876002886040516020016122e29190614244565b6040516020818303038152906040526040516122fe91906142ca565b602060405180830381855afa158015612319573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061233c91906142f4565b87876040516020016123539695949392919061452c565b60405160208183030381529060405260405161236f91906142ca565b602060405180830381855afa15801561238a573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612414576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240b9061444e565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561244a57612449613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161247e919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016124c793929190614629565b5f604051808303815f87803b1580156124de575f80fd5b505af11580156124f0573d5f803e3d5ffd5b505050505050505050505050565b6001600381111561251257612511613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561254457612543613ce0565b5b14612584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257b90614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146125f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125e990614fae565b60405180910390fd5b5f600333888860028960405160200161260b9190614244565b60405160208183030381529060405260405161262791906142ca565b602060405180830381855afa158015612642573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061266591906142f4565b88888860405160200161267e9796959493929190614384565b60405160208183030381529060405260405161269a91906142ca565b602060405180830381855afa1580156126b5573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461273f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127369061444e565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561277557612774613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0886040516127a9919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016127f494939291906144d6565b5f604051808303815f87803b15801561280b575f80fd5b505af115801561281d573d5f803e3d5ffd5b50505050505050505050505050565b600260048111156128405761283f613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561287357612872613ce0565b5b146128b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128aa9061503c565b60405180910390fd5b5f600387873388886002896040516020016128ce9190614244565b6040516020818303038152906040526040516128ea91906142ca565b602060405180830381855afa158015612905573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061292891906142f4565b8860405160200161293f979695949392919061465e565b60405160208183030381529060405260405161295b91906142ca565b602060405180830381855afa158015612976573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612a01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129f89061444e565b60405180910390fd5b600360015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115612a3857612a37613ce0565b5b02179055507f0d0da0df275f85bed3a5fe7ae79f3559341a3f9ccd8e010133438135bda00a878884604051612a6e929190614aee565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612b56573373ffffffffffffffffffffffffffffffffffffffff166108fc8890811502906040515f60405180830381858888f19350505050158015612aec573d5f803e3d5ffd5b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f19350505050158015612b50573d5f803e3d5ffd5b50612bd2565b5f829050612b8533898373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b612bd07f0000000000000000000000000000000000000000000000000000000000000000888373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b5050505050505050565b5f6004811115612bef57612bee613ce0565b5b60015f8b81526020019081526020015f205f01601c9054906101000a900460ff166004811115612c2257612c21613ce0565b5b14612c62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c59906150ca565b60405180910390fd5b5f8811612ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c9b90615132565b60405180910390fd5b5f8711612ce6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cdd9061519a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612d54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d4b90614d8f565b60405180910390fd5b5f60038989883389898d604051602001612d74979695949392919061465e565b604051602081830303815290604052604051612d9091906142ca565b602060405180830381855afa158015612dab573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115612e0357612e02613ce0565b5b81525060015f8c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115612ebe57612ebd613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358a604051612ef5919061447b565b60405180910390a15f879050612f3933308b8d612f129190614b42565b8473ffffffffffffffffffffffffffffffffffffffff16613543909392919063ffffffff16565b5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f808383810190612fc79190614807565b90505f6003811115612fdc57612fdb613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff16600381111561301157613010613ce0565b5b14613051576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161304890615228565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff16036130c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130ba9061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161312c90614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146131a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161319e90614a00565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614613215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161320c90614a68565b60405180910390fd5b5f8511613257576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161324e90615290565b60405180910390fd5b61326481602001516134b3565b156132a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161329b90614ad0565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c6040516020016132d49796959493929190614384565b6040516020818303038152906040526040516132f091906142ca565b602060405180830381855afa15801561330b573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561335b5761335a613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156133f2576133f1613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f015160405161342c919061447b565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b61353e838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85856040516024016134f79291906152ae565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b505050565b6135bf848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161357893929190614629565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b50505050565b5f6135ef828473ffffffffffffffffffffffffffffffffffffffff1661365a90919063ffffffff16565b90505f81511415801561361357508080602001905181019061361191906152ff565b155b1561365557826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161364c919061405c565b60405180910390fd5b505050565b606061366783835f61366f565b905092915050565b6060814710156136b657306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016136ad919061405c565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516136de91906142ca565b5f6040518083038185875af1925050503d805f8114613718576040519150601f19603f3d011682016040523d82523d5f602084013e61371d565b606091505b509150915061372d868383613738565b925050509392505050565b60608261374d57613748826137c5565b6137bd565b5f825114801561377357505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156137b557836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016137ac919061405c565b60405180910390fd5b8190506137be565b5b9392505050565b5f815111156137d75780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61384e8161381a565b8114613858575f80fd5b50565b5f8135905061386981613845565b92915050565b5f6020828403121561388457613883613812565b5b5f6138918482850161385b565b91505092915050565b5f8115159050919050565b6138ae8161389a565b82525050565b5f6020820190506138c75f8301846138a5565b92915050565b5f819050919050565b6138df816138cd565b81146138e9575f80fd5b50565b5f813590506138fa816138d6565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61392982613900565b9050919050565b6139398161391f565b8114613943575f80fd5b50565b5f8135905061395481613930565b92915050565b5f819050919050565b61396c8161395a565b8114613976575f80fd5b50565b5f8135905061398781613963565b92915050565b5f805f805f805f60e0888a0312156139a8576139a7613812565b5b5f6139b58a828b016138ec565b97505060206139c68a828b01613946565b96505060406139d78a828b016138ec565b95505060606139e88a828b016138ec565b94505060806139f98a828b01613946565b93505060a0613a0a8a828b01613979565b92505060c0613a1b8a828b01613979565b91505092959891949750929550565b5f805f805f8060c08789031215613a4457613a43613812565b5b5f613a5189828a016138ec565b9650506020613a6289828a01613946565b9550506040613a7389828a016138ec565b9450506060613a8489828a016138ec565b9350506080613a9589828a01613946565b92505060a0613aa689828a01613979565b9150509295509295509295565b5f805f805f805f60e0888a031215613ace57613acd613812565b5b5f613adb8a828b016138ec565b9750506020613aec8a828b01613979565b9650506040613afd8a828b01613979565b9550506060613b0e8a828b01613946565b9450506080613b1f8a828b016138ec565b93505060a0613b308a828b016138ec565b92505060c0613b418a828b01613946565b91505092959891949750929550565b5f80fd5b5f80fd5b5f80fd5b5f8083601f840112613b7157613b70613b50565b5b8235905067ffffffffffffffff811115613b8e57613b8d613b54565b5b602083019150836001820283011115613baa57613ba9613b58565b5b9250929050565b5f805f805f60808688031215613bca57613bc9613812565b5b5f613bd788828901613946565b9550506020613be888828901613946565b9450506040613bf988828901613979565b935050606086013567ffffffffffffffff811115613c1a57613c19613816565b5b613c2688828901613b5c565b92509250509295509295909350565b613c3e8161381a565b82525050565b5f602082019050613c575f830184613c35565b92915050565b5f60208284031215613c7257613c71613812565b5b5f613c7f848285016138ec565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b613cbc81613c88565b82525050565b5f63ffffffff82169050919050565b613cda81613cc2565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60058110613d1e57613d1d613ce0565b5b50565b5f819050613d2e82613d0d565b919050565b5f613d3d82613d21565b9050919050565b613d4d81613d33565b82525050565b5f608082019050613d665f830187613cb3565b613d736020830186613cd1565b613d806040830185613cd1565b613d8d6060830184613d44565b95945050505050565b613d9f81613cc2565b8114613da9575f80fd5b50565b5f81359050613dba81613d96565b92915050565b5f805f805f805f60e0888a031215613ddb57613dda613812565b5b5f613de88a828b016138ec565b9750506020613df98a828b01613979565b9650506040613e0a8a828b01613946565b9550506060613e1b8a828b016138ec565b9450506080613e2c8a828b016138ec565b93505060a0613e3d8a828b01613dac565b92505060c0613e4e8a828b01613dac565b91505092959891949750929550565b5f8083601f840112613e7257613e71613b50565b5b8235905067ffffffffffffffff811115613e8f57613e8e613b54565b5b602083019150836020820283011115613eab57613eaa613b58565b5b9250929050565b5f805f805f805f8060a0898b031215613ece57613ecd613812565b5b5f613edb8b828c01613946565b9850506020613eec8b828c01613946565b975050604089013567ffffffffffffffff811115613f0d57613f0c613816565b5b613f198b828c01613e5d565b9650965050606089013567ffffffffffffffff811115613f3c57613f3b613816565b5b613f488b828c01613e5d565b9450945050608089013567ffffffffffffffff811115613f6b57613f6a613816565b5b613f778b828c01613b5c565b92509250509295985092959890939650565b5f805f805f805f805f6101208a8c031215613fa757613fa6613812565b5b5f613fb48c828d016138ec565b9950506020613fc58c828d01613979565b9850506040613fd68c828d01613979565b9750506060613fe78c828d01613946565b9650506080613ff88c828d01613946565b95505060a06140098c828d016138ec565b94505060c061401a8c828d016138ec565b93505060e061402b8c828d01613dac565b92505061010061403d8c828d01613dac565b9150509295985092959850929598565b6140568161391f565b82525050565b5f60208201905061406f5f83018461404d565b92915050565b6004811061408657614085613ce0565b5b50565b5f81905061409682614075565b919050565b5f6140a582614089565b9050919050565b6140b58161409b565b82525050565b5f6060820190506140ce5f830186613cb3565b6140db6020830185613cd1565b6140e860408301846140ac565b949350505050565b5f805f805f8060a0878903121561410a57614109613812565b5b5f61411789828a01613946565b965050602061412889828a01613946565b955050604061413989828a01613979565b945050606061414a89828a01613979565b935050608087013567ffffffffffffffff81111561416b5761416a613816565b5b61417789828a01613b5c565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f6141f0602a83614186565b91506141fb82614196565b604082019050919050565b5f6020820190508181035f83015261421d816141e4565b9050919050565b5f819050919050565b61423e614239826138cd565b614224565b82525050565b5f61424f828461422d565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b5f5b8381101561428f578082015181840152602081019050614274565b5f8484015250505050565b5f6142a48261425e565b6142ae8185614268565b93506142be818560208601614272565b80840191505092915050565b5f6142d5828461429a565b915081905092915050565b5f815190506142ee816138d6565b92915050565b5f6020828403121561430957614308613812565b5b5f614316848285016142e0565b91505092915050565b5f8160601b9050919050565b5f6143358261431f565b9050919050565b5f6143468261432b565b9050919050565b61435e6143598261391f565b61433c565b82525050565b5f819050919050565b61437e6143798261395a565b614364565b82525050565b5f61438f828a61434d565b60148201915061439f828961434d565b6014820191506143af828861422d565b6020820191506143bf828761422d565b6020820191506143cf828661434d565b6014820191506143df828561436d565b6020820191506143ef828461436d565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f614438601383614186565b915061444382614404565b602082019050919050565b5f6020820190508181035f8301526144658161442c565b9050919050565b614475816138cd565b82525050565b5f60208201905061448e5f83018461446c565b92915050565b61449d8161395a565b82525050565b5f82825260208201905092915050565b50565b5f6144c15f836144a3565b91506144cc826144b3565b5f82019050919050565b5f60a0820190506144e95f83018761404d565b6144f6602083018661404d565b6145036040830185614494565b6145106060830184614494565b8181036080830152614521816144b6565b905095945050505050565b5f614537828961434d565b601482019150614547828861434d565b601482019150614557828761422d565b602082019150614567828661422d565b602082019150614577828561434d565b601482019150614587828461436d565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f6145f5603883614186565b91506146008261459b565b604082019050919050565b5f6020820190508181035f830152614622816145e9565b9050919050565b5f60608201905061463c5f83018661404d565b614649602083018561404d565b6146566040830184614494565b949350505050565b5f614669828a61436d565b602082019150614679828961436d565b602082019150614689828861434d565b601482019150614699828761434d565b6014820191506146a9828661422d565b6020820191506146b9828561422d565b6020820191506146c9828461434d565b60148201915081905098975050505050505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b614728826146e2565b810181811067ffffffffffffffff82111715614747576147466146f2565b5b80604052505050565b5f614759613809565b9050614765828261471f565b919050565b5f60c0828403121561477f5761477e6146de565b5b61478960c0614750565b90505f614798848285016138ec565b5f8301525060206147ab84828501613946565b60208301525060406147bf84828501613946565b60408301525060606147d3848285016138ec565b60608301525060806147e7848285016138ec565b60808301525060a06147fb84828501613dac565b60a08301525092915050565b5f60c0828403121561481c5761481b613812565b5b5f6148298482850161476a565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f61488c602a83614186565b915061489782614832565b604082019050919050565b5f6020820190508181035f8301526148b981614880565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f6148f4601e83614186565b91506148ff826148c0565b602082019050919050565b5f6020820190508181035f830152614921816148e8565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f61495c601e83614186565b915061496782614928565b602082019050919050565b5f6020820190508181035f83015261498981614950565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f6149ea602383614186565b91506149f582614990565b604082019050919050565b5f6020820190508181035f830152614a17816149de565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f614a52601b83614186565b9150614a5d82614a1e565b602082019050919050565b5f6020820190508181035f830152614a7f81614a46565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f614aba601a83614186565b9150614ac582614a86565b602082019050919050565b5f6020820190508181035f830152614ae781614aae565b9050919050565b5f604082019050614b015f83018561446c565b614b0e602083018461446c565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614b4c8261395a565b9150614b578361395a565b9250828201905080821115614b6f57614b6e614b15565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e74206f722054616b6572417070726f7665640000000000602082015250565b5f614bcf603b83614186565b9150614bda82614b75565b604082019050919050565b5f6020820190508181035f830152614bfc81614bc3565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e74207072652d617070726f7665206c6f636b2074696d65000000602082015250565b5f614c5d603d83614186565b9150614c6882614c03565b604082019050919050565b5f6020820190508181035f830152614c8a81614c51565b9050919050565b7f54616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f614ceb602483614186565b9150614cf682614c91565b604082019050919050565b5f6020820190508181035f830152614d1881614cdf565b9050919050565b7f5265636569766572206d757374206e6f74206265207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f614d79602183614186565b9150614d8482614d1f565b604082019050919050565b5f6020820190508181035f830152614da681614d6d565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f614e07602383614186565b9150614e1282614dad565b604082019050919050565b5f6020820190508181035f830152614e3481614dfb565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e20645f8201527f6578206665650000000000000000000000000000000000000000000000000000602082015250565b5f614e95602683614186565b9150614ea082614e3b565b604082019050919050565b5f6020820190508181035f830152614ec281614e89565b9050919050565b5f614ed38261395a565b9150614ede8361395a565b9250828203905081811115614ef657614ef5614b15565b5b92915050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f614f30601d83614186565b9150614f3b82614efc565b602082019050919050565b5f6020820190508181035f830152614f5d81614f24565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f614f98601583614186565b9150614fa382614f64565b602082019050919050565b5f6020820190508181035f830152614fc581614f8c565b9050919050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520545f8201527f616b6572417070726f7665640000000000000000000000000000000000000000602082015250565b5f615026602c83614186565b915061503182614fcc565b604082019050919050565b5f6020820190508181035f8301526150538161501a565b9050919050565b7f4552433230207632207061796d656e7420697320616c726561647920696e69745f8201527f69616c697a656400000000000000000000000000000000000000000000000000602082015250565b5f6150b4602783614186565b91506150bf8261505a565b604082019050919050565b5f6020820190508181035f8301526150e1816150a8565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f61511c601783614186565b9150615127826150e8565b602082019050919050565b5f6020820190508181035f83015261514981615110565b9050919050565b7f44657820666565206d757374206e6f74206265207a65726f00000000000000005f82015250565b5f615184601883614186565b915061518f82615150565b602082019050919050565b5f6020820190508181035f8301526151b181615178565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f615212602b83614186565b915061521d826151b8565b604082019050919050565b5f6020820190508181035f83015261523f81615206565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f61527a601c83614186565b915061528582615246565b602082019050919050565b5f6020820190508181035f8301526152a78161526e565b9050919050565b5f6040820190506152c15f83018561404d565b6152ce6020830184614494565b9392505050565b6152de8161389a565b81146152e8575f80fd5b50565b5f815190506152f9816152d5565b92915050565b5f6020828403121561531457615313613812565b5b5f615321848285016152eb565b9150509291505056fea26469706673582212200d86b0f6898fb823c55626c3b02a7098bc8622606b092e0f458df6c86ce2967864736f6c63430008180033"; +pub const NFT_MAKER_SWAP_V2_BYTES: &str = "6080604052348015600e575f80fd5b50612ffd8061001c5f395ff3fe608060405234801561000f575f80fd5b50600436106100a7575f3560e01c8063b27e46fb1161006f578063b27e46fb1461015f578063bc197c811461017b578063c8d9009b146101ab578063c92cd12d146101c7578063efccb9eb146101e3578063f23a6e6114610215576100a7565b806301ffc9a7146100ab57806305ec158d146100db5780630f235fce146100f7578063150b7a02146101135780636e6bf6d214610143575b5f80fd5b6100c560048036038101906100c09190611ebc565b610245565b6040516100d29190611f01565b60405180910390f35b6100f560048036038101906100f09190611fda565b610326565b005b610111600480360381019061010c9190612077565b6105e6565b005b61012d60048036038101906101289190612161565b6108a0565b60405161013a91906121f4565b60405180910390f35b61015d60048036038101906101589190612077565b610cef565b005b61017960048036038101906101749190611fda565b610faa565b005b61019560048036038101906101909190612262565b611269565b6040516101a291906121f4565b60405180910390f35b6101c560048036038101906101c09190612077565b6112a5565b005b6101e160048036038101906101dc9190611fda565b6115ce565b005b6101fd60048036038101906101f89190612339565b6118fc565b60405161020c9392919061242f565b60405180910390f35b61022f600480360381019061022a9190612464565b611948565b60405161023c91906121f4565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061030f57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061031f575061031e82611ddc565b5b9050919050565b6001600381111561033a576103396123bc565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561036c5761036b6123bc565b5b146103ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a39061257a565b60405180910390fd5b5f600387336002896040516020016103c491906125b8565b6040516020818303038152906040526040516103e09190612624565b602060405180830381855afa1580156103fb573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061041e919061264e565b8888888860405160200161043897969594939291906126de565b6040516020818303038152906040526040516104549190612624565b602060405180830381855afa15801561046f573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146104f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f0906127a8565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561052f5761052e6123bc565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd738860405161056391906127d5565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016105ae949392919061283f565b5f604051808303815f87803b1580156105c5575f80fd5b505af11580156105d7573d5f803e3d5ffd5b50505050505050505050505050565b600160038111156105fa576105f96123bc565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561062c5761062b6123bc565b5b1461066c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106639061257a565b60405180910390fd5b5f600386338787878760405160200161068a96959493929190612895565b6040516020818303038152906040526040516106a69190612624565b602060405180830381855afa1580156106c1573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461074b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610742906127a8565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156107b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ad90612974565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff021916908360038111156107ec576107eb6123bc565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad192190728760405161082091906127d5565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b815260040161086993929190612992565b5f604051808303815f87803b158015610880575f80fd5b505af1158015610892573d5f803e3d5ffd5b505050505050505050505050565b5f8083838101906108b19190612b1a565b90505f60038111156108c6576108c56123bc565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff1660038111156108fb576108fa6123bc565b5b1461093b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093290612bb5565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff16036109ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109a490612c1d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610a1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1690612c85565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8890612d13565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610aff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af690612d7b565b60405180910390fd5b610b0c8160200151611e45565b15610b4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4390612de3565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610b7a96959493929190612895565b604051602081830303815290604052604051610b969190612624565b602060405180830381855afa158015610bb1573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115610c0157610c006123bc565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115610c9857610c976123bc565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051610cd291906127d5565b60405180910390a163150b7a0260e01b9250505095945050505050565b60016003811115610d0357610d026123bc565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff166003811115610d3557610d346123bc565b5b14610d75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6c9061257a565b60405180910390fd5b5f60038633600288604051602001610d8d91906125b8565b604051602081830303815290604052604051610da99190612624565b602060405180830381855afa158015610dc4573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610de7919061264e565b878787604051602001610dff96959493929190612895565b604051602081830303815290604052604051610e1b9190612624565b602060405180830381855afa158015610e36573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610ec0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb7906127a8565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610ef657610ef56123bc565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051610f2a91906127d5565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610f7393929190612992565b5f604051808303815f87803b158015610f8a575f80fd5b505af1158015610f9c573d5f803e3d5ffd5b505050505050505050505050565b60016003811115610fbe57610fbd6123bc565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115610ff057610fef6123bc565b5b14611030576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110279061257a565b60405180910390fd5b5f60038733888888888860405160200161105097969594939291906126de565b60405160208183030381529060405260405161106c9190612624565b602060405180830381855afa158015611087573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611111576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611108906127a8565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff1642101561117c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117390612974565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156111b2576111b16123bc565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad19219072886040516111e691906127d5565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b8152600401611231949392919061283f565b5f604051808303815f87803b158015611248575f80fd5b505af115801561125a573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129c90612e4b565b60405180910390fd5b600160038111156112b9576112b86123bc565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff1660038111156112eb576112ea6123bc565b5b1461132b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113229061257a565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139090612eb3565b60405180910390fd5b5f60033387876002886040516020016113b291906125b8565b6040516020818303038152906040526040516113ce9190612624565b602060405180830381855afa1580156113e9573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061140c919061264e565b878760405160200161142396959493929190612895565b60405160208183030381529060405260405161143f9190612624565b602060405180830381855afa15801561145a573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146114e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114db906127a8565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561151a576115196123bc565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161154e91906127d5565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b815260040161159793929190612992565b5f604051808303815f87803b1580156115ae575f80fd5b505af11580156115c0573d5f803e3d5ffd5b505050505050505050505050565b600160038111156115e2576115e16123bc565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115611614576116136123bc565b5b14611654576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164b9061257a565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b990612eb3565b60405180910390fd5b5f60033388886002896040516020016116db91906125b8565b6040516020818303038152906040526040516116f79190612624565b602060405180830381855afa158015611712573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190611735919061264e565b88888860405160200161174e97969594939291906126de565b60405160208183030381529060405260405161176a9190612624565b602060405180830381855afa158015611785573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461180f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611806906127a8565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff02191690836003811115611845576118446123bc565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08860405161187991906127d5565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016118c4949392919061283f565b5f604051808303815f87803b1580156118db575f80fd5b505af11580156118ed573d5f803e3d5ffd5b50505050505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f8083838101906119599190612b1a565b90505f600381111561196e5761196d6123bc565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff1660038111156119a3576119a26123bc565b5b146119e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119da90612f41565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603611a55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4c90612c1d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603611ac7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611abe90612c85565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611b39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3090612d13565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614611ba7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9e90612d7b565b60405180910390fd5b5f8511611be9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be090612fa9565b60405180910390fd5b611bf68160200151611e45565b15611c36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2d90612de3565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c604051602001611c6697969594939291906126de565b604051602081830303815290604052604051611c829190612624565b602060405180830381855afa158015611c9d573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115611ced57611cec6123bc565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115611d8457611d836123bc565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051611dbe91906127d5565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611e9b81611e67565b8114611ea5575f80fd5b50565b5f81359050611eb681611e92565b92915050565b5f60208284031215611ed157611ed0611e5f565b5b5f611ede84828501611ea8565b91505092915050565b5f8115159050919050565b611efb81611ee7565b82525050565b5f602082019050611f145f830184611ef2565b92915050565b5f819050919050565b611f2c81611f1a565b8114611f36575f80fd5b50565b5f81359050611f4781611f23565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611f7682611f4d565b9050919050565b611f8681611f6c565b8114611f90575f80fd5b50565b5f81359050611fa181611f7d565b92915050565b5f819050919050565b611fb981611fa7565b8114611fc3575f80fd5b50565b5f81359050611fd481611fb0565b92915050565b5f805f805f805f60e0888a031215611ff557611ff4611e5f565b5b5f6120028a828b01611f39565b97505060206120138a828b01611f93565b96505060406120248a828b01611f39565b95505060606120358a828b01611f39565b94505060806120468a828b01611f93565b93505060a06120578a828b01611fc6565b92505060c06120688a828b01611fc6565b91505092959891949750929550565b5f805f805f8060c0878903121561209157612090611e5f565b5b5f61209e89828a01611f39565b96505060206120af89828a01611f93565b95505060406120c089828a01611f39565b94505060606120d189828a01611f39565b93505060806120e289828a01611f93565b92505060a06120f389828a01611fc6565b9150509295509295509295565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261212157612120612100565b5b8235905067ffffffffffffffff81111561213e5761213d612104565b5b60208301915083600182028301111561215a57612159612108565b5b9250929050565b5f805f805f6080868803121561217a57612179611e5f565b5b5f61218788828901611f93565b955050602061219888828901611f93565b94505060406121a988828901611fc6565b935050606086013567ffffffffffffffff8111156121ca576121c9611e63565b5b6121d68882890161210c565b92509250509295509295909350565b6121ee81611e67565b82525050565b5f6020820190506122075f8301846121e5565b92915050565b5f8083601f84011261222257612221612100565b5b8235905067ffffffffffffffff81111561223f5761223e612104565b5b60208301915083602082028301111561225b5761225a612108565b5b9250929050565b5f805f805f805f8060a0898b03121561227e5761227d611e5f565b5b5f61228b8b828c01611f93565b985050602061229c8b828c01611f93565b975050604089013567ffffffffffffffff8111156122bd576122bc611e63565b5b6122c98b828c0161220d565b9650965050606089013567ffffffffffffffff8111156122ec576122eb611e63565b5b6122f88b828c0161220d565b9450945050608089013567ffffffffffffffff81111561231b5761231a611e63565b5b6123278b828c0161210c565b92509250509295985092959890939650565b5f6020828403121561234e5761234d611e5f565b5b5f61235b84828501611f39565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b61239881612364565b82525050565b5f63ffffffff82169050919050565b6123b68161239e565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600481106123fa576123f96123bc565b5b50565b5f81905061240a826123e9565b919050565b5f612419826123fd565b9050919050565b6124298161240f565b82525050565b5f6060820190506124425f83018661238f565b61244f60208301856123ad565b61245c6040830184612420565b949350505050565b5f805f805f8060a0878903121561247e5761247d611e5f565b5b5f61248b89828a01611f93565b965050602061249c89828a01611f93565b95505060406124ad89828a01611fc6565b94505060606124be89828a01611fc6565b935050608087013567ffffffffffffffff8111156124df576124de611e63565b5b6124eb89828a0161210c565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f612564602a836124fa565b915061256f8261250a565b604082019050919050565b5f6020820190508181035f83015261259181612558565b9050919050565b5f819050919050565b6125b26125ad82611f1a565b612598565b82525050565b5f6125c382846125a1565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6125fe826125d2565b61260881856125dc565b93506126188185602086016125e6565b80840191505092915050565b5f61262f82846125f4565b915081905092915050565b5f8151905061264881611f23565b92915050565b5f6020828403121561266357612662611e5f565b5b5f6126708482850161263a565b91505092915050565b5f8160601b9050919050565b5f61268f82612679565b9050919050565b5f6126a082612685565b9050919050565b6126b86126b382611f6c565b612696565b82525050565b5f819050919050565b6126d86126d382611fa7565b6126be565b82525050565b5f6126e9828a6126a7565b6014820191506126f982896126a7565b60148201915061270982886125a1565b60208201915061271982876125a1565b60208201915061272982866126a7565b60148201915061273982856126c7565b60208201915061274982846126c7565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f6127926013836124fa565b915061279d8261275e565b602082019050919050565b5f6020820190508181035f8301526127bf81612786565b9050919050565b6127cf81611f1a565b82525050565b5f6020820190506127e85f8301846127c6565b92915050565b6127f781611f6c565b82525050565b61280681611fa7565b82525050565b5f82825260208201905092915050565b50565b5f61282a5f8361280c565b91506128358261281c565b5f82019050919050565b5f60a0820190506128525f8301876127ee565b61285f60208301866127ee565b61286c60408301856127fd565b61287960608301846127fd565b818103608083015261288a8161281f565b905095945050505050565b5f6128a082896126a7565b6014820191506128b082886126a7565b6014820191506128c082876125a1565b6020820191506128d082866125a1565b6020820191506128e082856126a7565b6014820191506128f082846126c7565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f61295e6038836124fa565b915061296982612904565b604082019050919050565b5f6020820190508181035f83015261298b81612952565b9050919050565b5f6060820190506129a55f8301866127ee565b6129b260208301856127ee565b6129bf60408301846127fd565b949350505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612a11826129cb565b810181811067ffffffffffffffff82111715612a3057612a2f6129db565b5b80604052505050565b5f612a42611e56565b9050612a4e8282612a08565b919050565b612a5c8161239e565b8114612a66575f80fd5b50565b5f81359050612a7781612a53565b92915050565b5f60c08284031215612a9257612a916129c7565b5b612a9c60c0612a39565b90505f612aab84828501611f39565b5f830152506020612abe84828501611f93565b6020830152506040612ad284828501611f93565b6040830152506060612ae684828501611f39565b6060830152506080612afa84828501611f39565b60808301525060a0612b0e84828501612a69565b60a08301525092915050565b5f60c08284031215612b2f57612b2e611e5f565b5b5f612b3c84828501612a7d565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f612b9f602a836124fa565b9150612baa82612b45565b604082019050919050565b5f6020820190508181035f830152612bcc81612b93565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612c07601e836124fa565b9150612c1282612bd3565b602082019050919050565b5f6020820190508181035f830152612c3481612bfb565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612c6f601e836124fa565b9150612c7a82612c3b565b602082019050919050565b5f6020820190508181035f830152612c9c81612c63565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f612cfd6023836124fa565b9150612d0882612ca3565b604082019050919050565b5f6020820190508181035f830152612d2a81612cf1565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f612d65601b836124fa565b9150612d7082612d31565b602082019050919050565b5f6020820190508181035f830152612d9281612d59565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f612dcd601a836124fa565b9150612dd882612d99565b602082019050919050565b5f6020820190508181035f830152612dfa81612dc1565b9050919050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f612e35601d836124fa565b9150612e4082612e01565b602082019050919050565b5f6020820190508181035f830152612e6281612e29565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f612e9d6015836124fa565b9150612ea882612e69565b602082019050919050565b5f6020820190508181035f830152612eca81612e91565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f612f2b602b836124fa565b9150612f3682612ed1565b604082019050919050565b5f6020820190508181035f830152612f5881612f1f565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f612f93601c836124fa565b9150612f9e82612f5f565b602082019050919050565b5f6020820190508181035f830152612fc081612f87565b905091905056fea2646970667358221220c066835d4b6ab57c60e10e6f680a4c26f0d64160b65fc0650c3d6e59f29798a164736f6c63430008190033"; pub trait CoinDockerOps { fn rpc_client(&self) -> &UtxoRpcClientEnum; @@ -1336,7 +1339,58 @@ pub fn init_geth_node() { if let Some(receipt) = deploy_nft_swap_tx_receipt { GETH_NFT_SWAP_CONTRACT = receipt.contract_address.unwrap(); - log!("GETH_NFT_SWAP_CONTRACT {:?}", GETH_SWAP_CONTRACT); + log!( + "GETH_NFT_SWAP_CONTRACT {:?}, receipt.status {:?}", + GETH_NFT_SWAP_CONTRACT, + receipt.status + ); + break; + } + thread::sleep(Duration::from_millis(100)); + } + + let tx_request_deploy_nft_maker_swap_v2_contract = TransactionRequest { + from: GETH_ACCOUNT, + to: None, + gas: None, + gas_price: None, + value: None, + data: Some(hex::decode(NFT_MAKER_SWAP_V2_BYTES).unwrap().into()), + nonce: None, + condition: None, + transaction_type: None, + access_list: None, + max_fee_per_gas: None, + max_priority_fee_per_gas: None, + }; + let deploy_nft_maker_swap_v2_tx_hash = block_on( + GETH_WEB3 + .eth() + .send_transaction(tx_request_deploy_nft_maker_swap_v2_contract), + ) + .unwrap(); + log!( + "Sent deploy nft swap contract transaction {:?}", + deploy_nft_maker_swap_v2_tx_hash + ); + + loop { + let deploy_nft_maker_swap_v2_tx_receipt = + match block_on(GETH_WEB3.eth().transaction_receipt(deploy_nft_maker_swap_v2_tx_hash)) { + Ok(receipt) => receipt, + Err(_) => { + thread::sleep(Duration::from_millis(100)); + continue; + }, + }; + + if let Some(receipt) = deploy_nft_maker_swap_v2_tx_receipt { + GETH_NFT_MAKER_SWAP_V2 = receipt.contract_address.unwrap(); + log!( + "GETH_NFT_MAKER_SWAP_V2 {:?}, receipt.status {:?}", + GETH_NFT_MAKER_SWAP_V2, + receipt.status + ); break; } thread::sleep(Duration::from_millis(100)); diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index f209e9afc2..6a1f179c5f 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1,7 +1,7 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC721_TEST_ABI, GETH_ACCOUNT, GETH_ERC1155_CONTRACT, GETH_ERC20_CONTRACT, GETH_ERC721_CONTRACT, - GETH_NFT_SWAP_CONTRACT, GETH_NONCE_LOCK, GETH_RPC_URL, GETH_SWAP_CONTRACT, - GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, MM_CTX}; + GETH_NFT_MAKER_SWAP_V2, GETH_NFT_SWAP_CONTRACT, GETH_NONCE_LOCK, GETH_RPC_URL, + GETH_SWAP_CONTRACT, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, MM_CTX}; use bitcrypto::{dhash160, sha256}; use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_request, EthCoin, ERC20_ABI}; use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; @@ -36,6 +36,11 @@ pub fn swap_contract() -> Address { unsafe { GETH_SWAP_CONTRACT } } /// GETH_NFT_SWAP_CONTRACT is set once during initialization before tests start pub fn nft_swap_contract() -> Address { unsafe { GETH_NFT_SWAP_CONTRACT } } +/// # Safety +/// +/// GETH_NFT_MAKER_SWAP_V2 is set once during initialization before tests start +pub fn nft_maker_swap_v2() -> Address { unsafe { GETH_NFT_MAKER_SWAP_V2 } } + /// # Safety /// /// GETH_WATCHERS_SWAP_CONTRACT is set once during initialization before tests start @@ -694,8 +699,8 @@ fn send_and_spend_erc721_maker_payment() { let erc721_nft = TestNftType::Erc721 { token_id: 2 }; - let maker_global_nft = global_nft_with_random_privkey(nft_swap_contract(), Some(erc721_nft)); - let taker_global_nft = global_nft_with_random_privkey(nft_swap_contract(), None); + let maker_global_nft = global_nft_with_random_privkey(nft_maker_swap_v2(), Some(erc721_nft)); + let taker_global_nft = global_nft_with_random_privkey(nft_maker_swap_v2(), None); let time_lock = now_sec() + 1000; let maker_pubkey = maker_global_nft.derive_htlc_pubkey(&[]); @@ -708,7 +713,7 @@ fn send_and_spend_erc721_maker_payment() { token_address: &erc721_contract(), token_id: &BigUint::from(2u32).to_bytes(), contract_type: &ContractType::Erc721, - swap_contract_address: &nft_swap_contract(), + swap_contract_address: &nft_maker_swap_v2(), }; let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { @@ -754,7 +759,7 @@ fn send_and_spend_erc721_maker_payment() { maker_pub: &maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), swap_unique_data: &[], contract_type: &ContractType::Erc721, - swap_contract_address: &nft_swap_contract(), + swap_contract_address: &nft_maker_swap_v2(), }; let spend_tx = block_on(taker_global_nft.spend_nft_maker_payment_v2(spend_payment_args)).unwrap(); From 44f542d6a61e041977be51af9a3d4fb0ee6b2d4d Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 18 Apr 2024 20:56:51 +0700 Subject: [PATCH 002/233] deploy contracts before tokens, add constructor to EtomicSwapMakerNftV2 contract, some --dev args in geth conf, impl wait_for_geth_node_ready --- mm2src/coins/eth.rs | 1 - mm2src/coins/eth/nft_maker_swap_v2_abi.json | 5 + .../tests/docker_tests/docker_tests_common.rs | 182 +++++++++--------- .../tests/docker_tests/eth_docker_tests.rs | 13 +- mm2src/mm2_main/tests/docker_tests_main.rs | 23 +++ 5 files changed, 130 insertions(+), 94 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 91350b72aa..ce88c3a352 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -4999,7 +4999,6 @@ impl EthCoin { }; if let Some(receipt) = web3_receipt { - println!("Receipt:\n{:?}", receipt); if receipt.status != Some(1.into()) { return MmError::err(Web3RpcError::Internal(ERRL!( "Tx receipt {:?} status of {} tx {:?} is failed", diff --git a/mm2src/coins/eth/nft_maker_swap_v2_abi.json b/mm2src/coins/eth/nft_maker_swap_v2_abi.json index 5ad7987f6f..95def23766 100644 --- a/mm2src/coins/eth/nft_maker_swap_v2_abi.json +++ b/mm2src/coins/eth/nft_maker_swap_v2_abi.json @@ -1,4 +1,9 @@ [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, { "anonymous": false, "inputs": [ diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 7091b39516..ffb396b1c0 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -116,7 +116,7 @@ pub const WATCHERS_SWAP_CONTRACT_BYTES: &str = "608060405234801561000f575f80fd5b pub const ERC721_TEST_TOKEN_BYTES: &str = "608060405234801562000010575f80fd5b50604051620022ac380380620022ac8339818101604052810190620000369190620001ea565b8181815f9081620000489190620004a4565b5080600190816200005a9190620004a4565b505050505062000588565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c6826200007e565b810181811067ffffffffffffffff82111715620000e857620000e76200008e565b5b80604052505050565b5f620000fc62000065565b90506200010a8282620000bb565b919050565b5f67ffffffffffffffff8211156200012c576200012b6200008e565b5b62000137826200007e565b9050602081019050919050565b5f5b838110156200016357808201518184015260208101905062000146565b5f8484015250505050565b5f620001846200017e846200010f565b620000f1565b905082815260208101848484011115620001a357620001a26200007a565b5b620001b084828562000144565b509392505050565b5f82601f830112620001cf57620001ce62000076565b5b8151620001e18482602086016200016e565b91505092915050565b5f80604083850312156200020357620002026200006e565b5b5f83015167ffffffffffffffff81111562000223576200022262000072565b5b6200023185828601620001b8565b925050602083015167ffffffffffffffff81111562000255576200025462000072565b5b6200026385828601620001b8565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620002bc57607f821691505b602082108103620002d257620002d162000277565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002f9565b620003428683620002f9565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200038c6200038662000380846200035a565b62000363565b6200035a565b9050919050565b5f819050919050565b620003a7836200036c565b620003bf620003b68262000393565b84845462000305565b825550505050565b5f90565b620003d5620003c7565b620003e28184846200039c565b505050565b5b818110156200040957620003fd5f82620003cb565b600181019050620003e8565b5050565b601f82111562000458576200042281620002d8565b6200042d84620002ea565b810160208510156200043d578190505b620004556200044c85620002ea565b830182620003e7565b50505b505050565b5f82821c905092915050565b5f6200047a5f19846008026200045d565b1980831691505092915050565b5f62000494838362000469565b9150826002028217905092915050565b620004af826200026d565b67ffffffffffffffff811115620004cb57620004ca6200008e565b5b620004d78254620002a4565b620004e48282856200040d565b5f60209050601f8311600181146200051a575f841562000505578287015190505b62000511858262000487565b86555062000580565b601f1984166200052a86620002d8565b5f5b8281101562000553578489015182556001820191506020850194506020810190506200052c565b868310156200057357848901516200056f601f89168262000469565b8355505b6001600288020188555050505b505050505050565b611d1680620005965f395ff3fe608060405234801561000f575f80fd5b50600436106100e8575f3560e01c80636352211e1161008a578063a22cb46511610064578063a22cb46514610258578063b88d4fde14610274578063c87b56dd14610290578063e985e9c5146102c0576100e8565b80636352211e146101da57806370a082311461020a57806395d89b411461023a576100e8565b8063095ea7b3116100c6578063095ea7b31461016a57806323b872dd1461018657806340c10f19146101a257806342842e0e146101be576100e8565b806301ffc9a7146100ec57806306fdde031461011c578063081812fc1461013a575b5f80fd5b610106600480360381019061010191906115a7565b6102f0565b60405161011391906115ec565b60405180910390f35b6101246103d1565b604051610131919061168f565b60405180910390f35b610154600480360381019061014f91906116e2565b610460565b604051610161919061174c565b60405180910390f35b610184600480360381019061017f919061178f565b61047b565b005b6101a0600480360381019061019b91906117cd565b610491565b005b6101bc60048036038101906101b7919061178f565b610590565b005b6101d860048036038101906101d391906117cd565b61059e565b005b6101f460048036038101906101ef91906116e2565b6105bd565b604051610201919061174c565b60405180910390f35b610224600480360381019061021f919061181d565b6105ce565b6040516102319190611857565b60405180910390f35b610242610684565b60405161024f919061168f565b60405180910390f35b610272600480360381019061026d919061189a565b610714565b005b61028e60048036038101906102899190611a04565b61072a565b005b6102aa60048036038101906102a591906116e2565b610747565b6040516102b7919061168f565b60405180910390f35b6102da60048036038101906102d59190611a84565b6107ad565b6040516102e791906115ec565b60405180910390f35b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103ba57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103ca57506103c98261083b565b5b9050919050565b60605f80546103df90611aef565b80601f016020809104026020016040519081016040528092919081815260200182805461040b90611aef565b80156104565780601f1061042d57610100808354040283529160200191610456565b820191905f5260205f20905b81548152906001019060200180831161043957829003601f168201915b5050505050905090565b5f61046a826108a4565b506104748261092a565b9050919050565b61048d8282610488610963565b61096a565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610501575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016104f8919061174c565b60405180910390fd5b5f610514838361050f610963565b61097c565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461058a578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161058193929190611b1f565b60405180910390fd5b50505050565b61059a8282610b87565b5050565b6105b883838360405180602001604052805f81525061072a565b505050565b5f6105c7826108a4565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361063f575f6040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401610636919061174c565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b60606001805461069390611aef565b80601f01602080910402602001604051908101604052809291908181526020018280546106bf90611aef565b801561070a5780601f106106e15761010080835404028352916020019161070a565b820191905f5260205f20905b8154815290600101906020018083116106ed57829003601f168201915b5050505050905090565b61072661071f610963565b8383610c7a565b5050565b610735848484610491565b61074184848484610de3565b50505050565b6060610752826108a4565b505f61075c610f95565b90505f81511161077a5760405180602001604052805f8152506107a5565b8061078484610fab565b604051602001610795929190611b8e565b6040516020818303038152906040525b915050919050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f806108af83611075565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361092157826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016109189190611857565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b61097783838360016110ae565b505050565b5f8061098784611075565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146109c8576109c781848661126d565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a5357610a075f855f806110ae565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610ad257600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610bf7575f6040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610bee919061174c565b60405180910390fd5b5f610c0383835f61097c565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c75575f6040517f73c6ac6e000000000000000000000000000000000000000000000000000000008152600401610c6c919061174c565b60405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610cea57816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401610ce1919061174c565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610dd691906115ec565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b1115610f8f578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02610e26610963565b8685856040518563ffffffff1660e01b8152600401610e489493929190611c03565b6020604051808303815f875af1925050508015610e8357506040513d601f19601f82011682018060405250810190610e809190611c61565b60015b610f04573d805f8114610eb1576040519150601f19603f3d011682016040523d82523d5f602084013e610eb6565b606091505b505f815103610efc57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610ef3919061174c565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614610f8d57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610f84919061174c565b60405180910390fd5b505b50505050565b606060405180602001604052805f815250905090565b60605f6001610fb984611330565b0190505f8167ffffffffffffffff811115610fd757610fd66118e0565b5b6040519080825280601f01601f1916602001820160405280156110095781602001600182028036833780820191505090505b5090505f82602001820190505b60011561106a578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161105f5761105e611c8c565b5b0494505f8503611016575b819350505050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b80806110e657505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611218575f6110f5846108a4565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561115f57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611172575061117081846107ad565b155b156111b457826040517fa9fbf51f0000000000000000000000000000000000000000000000000000000081526004016111ab919061174c565b60405180910390fd5b811561121657838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b611278838383611481565b61132b575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036112ec57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016112e39190611857565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401611322929190611cb9565b60405180910390fd5b505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061138c577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161138257611381611c8c565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106113c9576d04ee2d6d415b85acef810000000083816113bf576113be611c8c565b5b0492506020810190505b662386f26fc1000083106113f857662386f26fc1000083816113ee576113ed611c8c565b5b0492506010810190505b6305f5e1008310611421576305f5e100838161141757611416611c8c565b5b0492506008810190505b612710831061144657612710838161143c5761143b611c8c565b5b0492506004810190505b60648310611469576064838161145f5761145e611c8c565b5b0492506002810190505b600a8310611478576001810190505b80915050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561153857508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806114f957506114f884846107ad565b5b8061153757508273ffffffffffffffffffffffffffffffffffffffff1661151f8361092a565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61158681611552565b8114611590575f80fd5b50565b5f813590506115a18161157d565b92915050565b5f602082840312156115bc576115bb61154a565b5b5f6115c984828501611593565b91505092915050565b5f8115159050919050565b6115e6816115d2565b82525050565b5f6020820190506115ff5f8301846115dd565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561163c578082015181840152602081019050611621565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61166182611605565b61166b818561160f565b935061167b81856020860161161f565b61168481611647565b840191505092915050565b5f6020820190508181035f8301526116a78184611657565b905092915050565b5f819050919050565b6116c1816116af565b81146116cb575f80fd5b50565b5f813590506116dc816116b8565b92915050565b5f602082840312156116f7576116f661154a565b5b5f611704848285016116ce565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6117368261170d565b9050919050565b6117468161172c565b82525050565b5f60208201905061175f5f83018461173d565b92915050565b61176e8161172c565b8114611778575f80fd5b50565b5f8135905061178981611765565b92915050565b5f80604083850312156117a5576117a461154a565b5b5f6117b28582860161177b565b92505060206117c3858286016116ce565b9150509250929050565b5f805f606084860312156117e4576117e361154a565b5b5f6117f18682870161177b565b93505060206118028682870161177b565b9250506040611813868287016116ce565b9150509250925092565b5f602082840312156118325761183161154a565b5b5f61183f8482850161177b565b91505092915050565b611851816116af565b82525050565b5f60208201905061186a5f830184611848565b92915050565b611879816115d2565b8114611883575f80fd5b50565b5f8135905061189481611870565b92915050565b5f80604083850312156118b0576118af61154a565b5b5f6118bd8582860161177b565b92505060206118ce85828601611886565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61191682611647565b810181811067ffffffffffffffff82111715611935576119346118e0565b5b80604052505050565b5f611947611541565b9050611953828261190d565b919050565b5f67ffffffffffffffff821115611972576119716118e0565b5b61197b82611647565b9050602081019050919050565b828183375f83830152505050565b5f6119a86119a384611958565b61193e565b9050828152602081018484840111156119c4576119c36118dc565b5b6119cf848285611988565b509392505050565b5f82601f8301126119eb576119ea6118d8565b5b81356119fb848260208601611996565b91505092915050565b5f805f8060808587031215611a1c57611a1b61154a565b5b5f611a298782880161177b565b9450506020611a3a8782880161177b565b9350506040611a4b878288016116ce565b925050606085013567ffffffffffffffff811115611a6c57611a6b61154e565b5b611a78878288016119d7565b91505092959194509250565b5f8060408385031215611a9a57611a9961154a565b5b5f611aa78582860161177b565b9250506020611ab88582860161177b565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611b0657607f821691505b602082108103611b1957611b18611ac2565b5b50919050565b5f606082019050611b325f83018661173d565b611b3f6020830185611848565b611b4c604083018461173d565b949350505050565b5f81905092915050565b5f611b6882611605565b611b728185611b54565b9350611b8281856020860161161f565b80840191505092915050565b5f611b998285611b5e565b9150611ba58284611b5e565b91508190509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f611bd582611bb1565b611bdf8185611bbb565b9350611bef81856020860161161f565b611bf881611647565b840191505092915050565b5f608082019050611c165f83018761173d565b611c23602083018661173d565b611c306040830185611848565b8181036060830152611c428184611bcb565b905095945050505050565b5f81519050611c5b8161157d565b92915050565b5f60208284031215611c7657611c7561154a565b5b5f611c8384828501611c4d565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f604082019050611ccc5f83018561173d565b611cd96020830184611848565b939250505056fea26469706673582212207439b47c2a9a1624955997732075917bbf1da26949d000c778f561eb5687576164736f6c63430008180033"; pub const ERC1155_TEST_TOKEN_BYTES: &str = "608060405234801562000010575f80fd5b50604051620024eb380380620024eb8339818101604052810190620000369190620001ea565b8062000048816200005060201b60201c565b505062000554565b806002908162000061919062000470565b5050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c6826200007e565b810181811067ffffffffffffffff82111715620000e857620000e76200008e565b5b80604052505050565b5f620000fc62000065565b90506200010a8282620000bb565b919050565b5f67ffffffffffffffff8211156200012c576200012b6200008e565b5b62000137826200007e565b9050602081019050919050565b5f5b838110156200016357808201518184015260208101905062000146565b5f8484015250505050565b5f620001846200017e846200010f565b620000f1565b905082815260208101848484011115620001a357620001a26200007a565b5b620001b084828562000144565b509392505050565b5f82601f830112620001cf57620001ce62000076565b5b8151620001e18482602086016200016e565b91505092915050565b5f602082840312156200020257620002016200006e565b5b5f82015167ffffffffffffffff81111562000222576200022162000072565b5b6200023084828501620001b8565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200028857607f821691505b6020821081036200029e576200029d62000243565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002c5565b6200030e8683620002c5565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f62000358620003526200034c8462000326565b6200032f565b62000326565b9050919050565b5f819050919050565b620003738362000338565b6200038b62000382826200035f565b848454620002d1565b825550505050565b5f90565b620003a162000393565b620003ae81848462000368565b505050565b5b81811015620003d557620003c95f8262000397565b600181019050620003b4565b5050565b601f8211156200042457620003ee81620002a4565b620003f984620002b6565b8101602085101562000409578190505b620004216200041885620002b6565b830182620003b3565b50505b505050565b5f82821c905092915050565b5f620004465f198460080262000429565b1980831691505092915050565b5f62000460838362000435565b9150826002028217905092915050565b6200047b8262000239565b67ffffffffffffffff8111156200049757620004966200008e565b5b620004a3825462000270565b620004b0828285620003d9565b5f60209050601f831160018114620004e6575f8415620004d1578287015190505b620004dd858262000453565b8655506200054c565b601f198416620004f686620002a4565b5f5b828110156200051f57848901518255600182019150602085019450602081019050620004f8565b868310156200053f57848901516200053b601f89168262000435565b8355505b6001600288020188555050505b505050505050565b611f8980620005625f395ff3fe608060405234801561000f575f80fd5b5060043610610090575f3560e01c80634e1273f4116100645780634e1273f414610140578063731133e914610170578063a22cb4651461018c578063e985e9c5146101a8578063f242432a146101d857610090565b8062fdd58e1461009457806301ffc9a7146100c45780630e89341c146100f45780632eb2c2d614610124575b5f80fd5b6100ae60048036038101906100a991906113bd565b6101f4565b6040516100bb919061140a565b60405180910390f35b6100de60048036038101906100d99190611478565b610249565b6040516100eb91906114bd565b60405180910390f35b61010e600480360381019061010991906114d6565b61032a565b60405161011b919061158b565b60405180910390f35b61013e6004803603810190610139919061179b565b6103bc565b005b61015a60048036038101906101559190611926565b610463565b6040516101679190611a53565b60405180910390f35b61018a60048036038101906101859190611a73565b61056a565b005b6101a660048036038101906101a19190611b1d565b61057c565b005b6101c260048036038101906101bd9190611b5b565b610592565b6040516101cf91906114bd565b60405180910390f35b6101f260048036038101906101ed9190611b99565b610620565b005b5f805f8381526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f7fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061031357507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103235750610322826106c7565b5b9050919050565b60606002805461033990611c59565b80601f016020809104026020016040519081016040528092919081815260200182805461036590611c59565b80156103b05780601f10610387576101008083540402835291602001916103b0565b820191905f5260205f20905b81548152906001019060200180831161039357829003601f168201915b50505050509050919050565b5f6103c5610730565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561040a57506104088682610592565b155b1561044e5780866040517fe237d922000000000000000000000000000000000000000000000000000000008152600401610445929190611c98565b60405180910390fd5b61045b8686868686610737565b505050505050565b606081518351146104af57815183516040517f5b0599910000000000000000000000000000000000000000000000000000000081526004016104a6929190611cbf565b60405180910390fd5b5f835167ffffffffffffffff8111156104cb576104ca6115af565b5b6040519080825280602002602001820160405280156104f95781602001602082028036833780820191505090505b5090505f5b845181101561055f5761053561051d828761082b90919063ffffffff16565b610530838761083e90919063ffffffff16565b6101f4565b82828151811061054857610547611ce6565b5b6020026020010181815250508060010190506104fe565b508091505092915050565b61057684848484610851565b50505050565b61058e610587610730565b83836108e6565b5050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f610629610730565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561066e575061066c8682610592565b155b156106b25780866040517fe237d9220000000000000000000000000000000000000000000000000000000081526004016106a9929190611c98565b60405180910390fd5b6106bf8686868686610a4f565b505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036107a7575f6040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161079e9190611d13565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610817575f6040517f01a8351400000000000000000000000000000000000000000000000000000000815260040161080e9190611d13565b60405180910390fd5b6108248585858585610b55565b5050505050565b5f60208202602084010151905092915050565b5f60208202602084010151905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036108c1575f6040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016108b89190611d13565b60405180910390fd5b5f806108cd8585610c01565b915091506108de5f87848487610b55565b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610956575f6040517fced3e10000000000000000000000000000000000000000000000000000000000815260040161094d9190611d13565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610a4291906114bd565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610abf575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401610ab69190611d13565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610b2f575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401610b269190611d13565b60405180910390fd5b5f80610b3b8585610c01565b91509150610b4c8787848487610b55565b50505050505050565b610b6185858585610c31565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610bfa575f610b9d610730565b90506001845103610be9575f610bbc5f8661083e90919063ffffffff16565b90505f610bd25f8661083e90919063ffffffff16565b9050610be2838989858589610fc1565b5050610bf8565b610bf7818787878787611170565b5b505b5050505050565b60608060405191506001825283602083015260408201905060018152826020820152604081016040529250929050565b8051825114610c7b57815181516040517f5b059991000000000000000000000000000000000000000000000000000000008152600401610c72929190611cbf565b60405180910390fd5b5f610c84610730565b90505f5b8351811015610e80575f610ca5828661083e90919063ffffffff16565b90505f610cbb838661083e90919063ffffffff16565b90505f73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614610dde575f805f8481526020019081526020015f205f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015610d8a57888183856040517f03dee4c5000000000000000000000000000000000000000000000000000000008152600401610d819493929190611d2c565b60405180910390fd5b8181035f808581526020019081526020015f205f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610e7357805f808481526020019081526020015f205f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610e6b9190611d9c565b925050819055505b5050806001019050610c88565b506001835103610f3b575f610e9e5f8561083e90919063ffffffff16565b90505f610eb45f8561083e90919063ffffffff16565b90508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051610f2c929190611cbf565b60405180910390a45050610fba565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051610fb1929190611dcf565b60405180910390a45b5050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115611168578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b8152600401611021959493929190611e56565b6020604051808303815f875af192505050801561105c57506040513d601f19601f820116820180604052508101906110599190611ec2565b60015b6110dd573d805f811461108a576040519150601f19603f3d011682016040523d82523d5f602084013e61108f565b606091505b505f8151036110d557846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016110cc9190611d13565b60405180910390fd5b805181602001fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461116657846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161115d9190611d13565b60405180910390fd5b505b505050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115611317578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b81526004016111d0959493929190611eed565b6020604051808303815f875af192505050801561120b57506040513d601f19601f820116820180604052508101906112089190611ec2565b60015b61128c573d805f8114611239576040519150601f19603f3d011682016040523d82523d5f602084013e61123e565b606091505b505f81510361128457846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161127b9190611d13565b60405180910390fd5b805181602001fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461131557846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161130c9190611d13565b60405180910390fd5b505b505050505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61135982611330565b9050919050565b6113698161134f565b8114611373575f80fd5b50565b5f8135905061138481611360565b92915050565b5f819050919050565b61139c8161138a565b81146113a6575f80fd5b50565b5f813590506113b781611393565b92915050565b5f80604083850312156113d3576113d2611328565b5b5f6113e085828601611376565b92505060206113f1858286016113a9565b9150509250929050565b6114048161138a565b82525050565b5f60208201905061141d5f8301846113fb565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61145781611423565b8114611461575f80fd5b50565b5f813590506114728161144e565b92915050565b5f6020828403121561148d5761148c611328565b5b5f61149a84828501611464565b91505092915050565b5f8115159050919050565b6114b7816114a3565b82525050565b5f6020820190506114d05f8301846114ae565b92915050565b5f602082840312156114eb576114ea611328565b5b5f6114f8848285016113a9565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561153857808201518184015260208101905061151d565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61155d82611501565b611567818561150b565b935061157781856020860161151b565b61158081611543565b840191505092915050565b5f6020820190508181035f8301526115a38184611553565b905092915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6115e582611543565b810181811067ffffffffffffffff82111715611604576116036115af565b5b80604052505050565b5f61161661131f565b905061162282826115dc565b919050565b5f67ffffffffffffffff821115611641576116406115af565b5b602082029050602081019050919050565b5f80fd5b5f61166861166384611627565b61160d565b9050808382526020820190506020840283018581111561168b5761168a611652565b5b835b818110156116b457806116a088826113a9565b84526020840193505060208101905061168d565b5050509392505050565b5f82601f8301126116d2576116d16115ab565b5b81356116e2848260208601611656565b91505092915050565b5f80fd5b5f67ffffffffffffffff821115611709576117086115af565b5b61171282611543565b9050602081019050919050565b828183375f83830152505050565b5f61173f61173a846116ef565b61160d565b90508281526020810184848401111561175b5761175a6116eb565b5b61176684828561171f565b509392505050565b5f82601f830112611782576117816115ab565b5b813561179284826020860161172d565b91505092915050565b5f805f805f60a086880312156117b4576117b3611328565b5b5f6117c188828901611376565b95505060206117d288828901611376565b945050604086013567ffffffffffffffff8111156117f3576117f261132c565b5b6117ff888289016116be565b935050606086013567ffffffffffffffff8111156118205761181f61132c565b5b61182c888289016116be565b925050608086013567ffffffffffffffff81111561184d5761184c61132c565b5b6118598882890161176e565b9150509295509295909350565b5f67ffffffffffffffff8211156118805761187f6115af565b5b602082029050602081019050919050565b5f6118a361189e84611866565b61160d565b905080838252602082019050602084028301858111156118c6576118c5611652565b5b835b818110156118ef57806118db8882611376565b8452602084019350506020810190506118c8565b5050509392505050565b5f82601f83011261190d5761190c6115ab565b5b813561191d848260208601611891565b91505092915050565b5f806040838503121561193c5761193b611328565b5b5f83013567ffffffffffffffff8111156119595761195861132c565b5b611965858286016118f9565b925050602083013567ffffffffffffffff8111156119865761198561132c565b5b611992858286016116be565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6119ce8161138a565b82525050565b5f6119df83836119c5565b60208301905092915050565b5f602082019050919050565b5f611a018261199c565b611a0b81856119a6565b9350611a16836119b6565b805f5b83811015611a46578151611a2d88826119d4565b9750611a38836119eb565b925050600181019050611a19565b5085935050505092915050565b5f6020820190508181035f830152611a6b81846119f7565b905092915050565b5f805f8060808587031215611a8b57611a8a611328565b5b5f611a9887828801611376565b9450506020611aa9878288016113a9565b9350506040611aba878288016113a9565b925050606085013567ffffffffffffffff811115611adb57611ada61132c565b5b611ae78782880161176e565b91505092959194509250565b611afc816114a3565b8114611b06575f80fd5b50565b5f81359050611b1781611af3565b92915050565b5f8060408385031215611b3357611b32611328565b5b5f611b4085828601611376565b9250506020611b5185828601611b09565b9150509250929050565b5f8060408385031215611b7157611b70611328565b5b5f611b7e85828601611376565b9250506020611b8f85828601611376565b9150509250929050565b5f805f805f60a08688031215611bb257611bb1611328565b5b5f611bbf88828901611376565b9550506020611bd088828901611376565b9450506040611be1888289016113a9565b9350506060611bf2888289016113a9565b925050608086013567ffffffffffffffff811115611c1357611c1261132c565b5b611c1f8882890161176e565b9150509295509295909350565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611c7057607f821691505b602082108103611c8357611c82611c2c565b5b50919050565b611c928161134f565b82525050565b5f604082019050611cab5f830185611c89565b611cb86020830184611c89565b9392505050565b5f604082019050611cd25f8301856113fb565b611cdf60208301846113fb565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f602082019050611d265f830184611c89565b92915050565b5f608082019050611d3f5f830187611c89565b611d4c60208301866113fb565b611d5960408301856113fb565b611d6660608301846113fb565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611da68261138a565b9150611db18361138a565b9250828201905080821115611dc957611dc8611d6f565b5b92915050565b5f6040820190508181035f830152611de781856119f7565b90508181036020830152611dfb81846119f7565b90509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f611e2882611e04565b611e328185611e0e565b9350611e4281856020860161151b565b611e4b81611543565b840191505092915050565b5f60a082019050611e695f830188611c89565b611e766020830187611c89565b611e8360408301866113fb565b611e9060608301856113fb565b8181036080830152611ea28184611e1e565b90509695505050505050565b5f81519050611ebc8161144e565b92915050565b5f60208284031215611ed757611ed6611328565b5b5f611ee484828501611eae565b91505092915050565b5f60a082019050611f005f830188611c89565b611f0d6020830187611c89565b8181036040830152611f1f81866119f7565b90508181036060830152611f3381856119f7565b90508181036080830152611f478184611e1e565b9050969550505050505056fea26469706673582212203835581c6344b12728c44fa4d9e912cd60e64012c1b772bb703d1c36825c16fd64736f6c63430008180033"; pub const NFT_SWAP_CONTRACT_BYTES: &str = "60a060405234801562000010575f80fd5b50604051620055a2380380620055a2833981810160405281019062000036919062000147565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200009e90620001fb565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506200021b565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200011182620000e6565b9050919050565b620001238162000105565b81146200012e575f80fd5b50565b5f81519050620001418162000118565b92915050565b5f602082840312156200015f576200015e620000e2565b5b5f6200016e8482850162000131565b91505092915050565b5f82825260208201905092915050565b7f66656541646472657373206d757374206e6f74206265207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f620001e360238362000177565b9150620001f08262000187565b604082019050919050565b5f6020820190508181035f8301526200021481620001d5565b9050919050565b608051615360620002425f395f8181612aef01528181612b8a0152612f4801526153605ff3fe608060405260043610610113575f3560e01c80639b4603f21161009f578063cc90c19911610063578063cc90c1991461038e578063d6a71eb4146103b6578063e06cf966146103de578063efccb9eb14610408578063f23a6e611461044657610113565b80639b4603f2146102be578063b27e46fb146102da578063bc197c8114610302578063c8d9009b1461033e578063c92cd12d1461036657610113565b8063150b7a02116100e6578063150b7a02146101cb5780633e6af5f21461020757806346b95ac71461022f57806365e266171461026e5780636e6bf6d21461029657610113565b806301ffc9a71461011757806305ec158d146101535780630f235fce1461017b578063146e5b24146101a3575b5f80fd5b348015610122575f80fd5b5061013d6004803603810190610138919061386f565b610482565b60405161014a91906138b4565b60405180910390f35b34801561015e575f80fd5b506101796004803603810190610174919061398d565b610563565b005b348015610186575f80fd5b506101a1600480360381019061019c9190613a2a565b610823565b005b3480156101ae575f80fd5b506101c960048036038101906101c49190613ab3565b610add565b005b3480156101d6575f80fd5b506101f160048036038101906101ec9190613bb1565b610cc3565b6040516101fe9190613c44565b60405180910390f35b348015610212575f80fd5b5061022d60048036038101906102289190613ab3565b611112565b005b34801561023a575f80fd5b5061025560048036038101906102509190613c5d565b611423565b6040516102659493929190613d53565b60405180910390f35b348015610279575f80fd5b50610294600480360381019061028f9190613ab3565b611485565b005b3480156102a1575f80fd5b506102bc60048036038101906102b79190613a2a565b6118e9565b005b6102d860048036038101906102d39190613dc0565b611ba4565b005b3480156102e5575f80fd5b5061030060048036038101906102fb919061398d565b611eda565b005b34801561030d575f80fd5b5061032860048036038101906103239190613eb2565b612199565b6040516103359190613c44565b60405180910390f35b348015610349575f80fd5b50610364600480360381019061035f9190613a2a565b6121d5565b005b348015610371575f80fd5b5061038c6004803603810190610387919061398d565b6124fe565b005b348015610399575f80fd5b506103b460048036038101906103af9190613ab3565b61282c565b005b3480156103c1575f80fd5b506103dc60048036038101906103d79190613f89565b612bdc565b005b3480156103e9575f80fd5b506103f2612f46565b6040516103ff919061405c565b60405180910390f35b348015610413575f80fd5b5061042e60048036038101906104299190613c5d565b612f6a565b60405161043d939291906140bb565b60405180910390f35b348015610451575f80fd5b5061046c600480360381019061046791906140f0565b612fb6565b6040516104799190613c44565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061054c57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061055c575061055b8261344a565b5b9050919050565b6001600381111561057757610576613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff1660038111156105a9576105a8613ce0565b5b146105e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e090614206565b60405180910390fd5b5f600387336002896040516020016106019190614244565b60405160208183030381529060405260405161061d91906142ca565b602060405180830381855afa158015610638573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065b91906142f4565b888888886040516020016106759796959493929190614384565b60405160208183030381529060405260405161069191906142ca565b602060405180830381855afa1580156106ac573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610736576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072d9061444e565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561076c5761076b613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd73886040516107a0919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016107eb94939291906144d6565b5f604051808303815f87803b158015610802575f80fd5b505af1158015610814573d5f803e3d5ffd5b50505050505050505050505050565b6001600381111561083757610836613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561086957610868613ce0565b5b146108a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a090614206565b60405180910390fd5b5f60038633878787876040516020016108c79695949392919061452c565b6040516020818303038152906040526040516108e391906142ca565b602060405180830381855afa1580156108fe573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097f9061444e565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156109f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ea9061460b565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610a2957610a28613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907287604051610a5d919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610aa693929190614629565b5f604051808303815f87803b158015610abd575f80fd5b505af1158015610acf573d5f803e3d5ffd5b505050505050505050505050565b60016004811115610af157610af0613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115610b2457610b23613ce0565b5b14610b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5b90614206565b60405180910390fd5b5f600387878733888888604051602001610b84979695949392919061465e565b604051602081830303815290604052604051610ba091906142ca565b602060405180830381855afa158015610bbb573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610c46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3d9061444e565b60405180910390fd5b600260015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610c7d57610c7c613ce0565b5b02179055507f9c45e43e2ef051f70491ffd5221bf02ab37e1324128714ef9610df5f24fc9fb588604051610cb1919061447b565b60405180910390a15050505050505050565b5f808383810190610cd49190614807565b90505f6003811115610ce957610ce8613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff166003811115610d1e57610d1d613ce0565b5b14610d5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d55906148a2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603610dd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc79061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610e42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3990614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610eb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eab90614a00565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610f22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1990614a68565b60405180910390fd5b610f2f81602001516134b3565b15610f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6690614ad0565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610f9d9695949392919061452c565b604051602081830303815290604052604051610fb991906142ca565b602060405180830381855afa158015610fd4573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561102457611023613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156110bb576110ba613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f01516040516110f5919061447b565b60405180910390a163150b7a0260e01b9250505095945050505050565b6001600481111561112657611125613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561115957611158613ce0565b5b14611199576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119090614206565b60405180910390fd5b5f6003878787336002896040516020016111b39190614244565b6040516020818303038152906040526040516111cf91906142ca565b602060405180830381855afa1580156111ea573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061120d91906142f4565b8888604051602001611225979695949392919061465e565b60405160208183030381529060405260405161124191906142ca565b602060405180830381855afa15801561125c573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146112e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112de9061444e565b60405180910390fd5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff0219169083600481111561131e5761131d613ce0565b5b02179055507f45169a52eef651b20a81474b50b8a5d83225225fcd097ef3cf7952d9ab304f278885604051611354929190614aee565b60405180910390a15f86886113699190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113e7573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156113e1573d5f803e3d5ffd5b50611418565b5f83905061141633838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b6001602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900463ffffffff1690805f01601c9054906101000a900460ff16905084565b6001600481111561149957611498613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff1660048111156114cc576114cb613ce0565b5b148061151c5750600260048111156114e7576114e6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561151a57611519613ce0565b5b145b61155b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155290614be5565b60405180910390fd5b5f60038787873388888860405160200161157b979695949392919061465e565b60405160208183030381529060405260405161159791906142ca565b602060405180830381855afa1580156115b2573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461163d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116349061444e565b60405180910390fd5b6002600481111561165157611650613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561168457611683613ce0565b5b036116f65760015f8981526020019081526020015f205f0160189054906101000a900463ffffffff1663ffffffff164210156116f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ec9061460b565b60405180910390fd5b5b6001600481111561170a57611709613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561173d5761173c613ce0565b5b036117af5760015f8981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156117ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a590614c73565b60405180910390fd5b5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156117e6576117e5613ce0565b5b02179055507fbdd7a4be6d82798a500b59077706b12d3f45acf5504828919f92501307b2b9538860405161181a919061447b565b60405180910390a15f868861182f9190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118ad573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156118a7573d5f803e3d5ffd5b506118de565b5f8390506118dc33838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b600160038111156118fd576118fc613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561192f5761192e613ce0565b5b1461196f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196690614206565b60405180910390fd5b5f600386336002886040516020016119879190614244565b6040516020818303038152906040526040516119a391906142ca565b602060405180830381855afa1580156119be573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906119e191906142f4565b8787876040516020016119f99695949392919061452c565b604051602081830303815290604052604051611a1591906142ca565b602060405180830381855afa158015611a30573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611aba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab19061444e565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115611af057611aef613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051611b24919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401611b6d93929190614629565b5f604051808303815f87803b158015611b84575f80fd5b505af1158015611b96573d5f803e3d5ffd5b505050505050505050505050565b5f6004811115611bb757611bb6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115611bea57611be9613ce0565b5b14611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2190614d01565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611c98576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8f90614d8f565b60405180910390fd5b5f3411611cda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd190614e1d565b60405180910390fd5b853411611d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1390614eab565b60405180910390fd5b5f60038734611d2b9190614ec9565b88883389895f604051602001611d47979695949392919061465e565b604051602081830303815290604052604051611d6391906142ca565b602060405180830381855afa158015611d7e573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115611dd657611dd5613ce0565b5b81525060015f8a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115611e9157611e90613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd93588604051611ec8919061447b565b60405180910390a15050505050505050565b60016003811115611eee57611eed613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115611f2057611f1f613ce0565b5b14611f60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5790614206565b60405180910390fd5b5f600387338888888888604051602001611f809796959493929190614384565b604051602081830303815290604052604051611f9c91906142ca565b602060405180830381855afa158015611fb7573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612041576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120389061444e565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156120ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a39061460b565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156120e2576120e1613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907288604051612116919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161216194939291906144d6565b5f604051808303815f87803b158015612178575f80fd5b505af115801561218a573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121cc90614f46565b60405180910390fd5b600160038111156121e9576121e8613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561221b5761221a613ce0565b5b1461225b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161225290614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c090614fae565b60405180910390fd5b5f60033387876002886040516020016122e29190614244565b6040516020818303038152906040526040516122fe91906142ca565b602060405180830381855afa158015612319573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061233c91906142f4565b87876040516020016123539695949392919061452c565b60405160208183030381529060405260405161236f91906142ca565b602060405180830381855afa15801561238a573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612414576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240b9061444e565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561244a57612449613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161247e919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016124c793929190614629565b5f604051808303815f87803b1580156124de575f80fd5b505af11580156124f0573d5f803e3d5ffd5b505050505050505050505050565b6001600381111561251257612511613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561254457612543613ce0565b5b14612584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257b90614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146125f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125e990614fae565b60405180910390fd5b5f600333888860028960405160200161260b9190614244565b60405160208183030381529060405260405161262791906142ca565b602060405180830381855afa158015612642573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061266591906142f4565b88888860405160200161267e9796959493929190614384565b60405160208183030381529060405260405161269a91906142ca565b602060405180830381855afa1580156126b5573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461273f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127369061444e565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561277557612774613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0886040516127a9919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016127f494939291906144d6565b5f604051808303815f87803b15801561280b575f80fd5b505af115801561281d573d5f803e3d5ffd5b50505050505050505050505050565b600260048111156128405761283f613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561287357612872613ce0565b5b146128b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128aa9061503c565b60405180910390fd5b5f600387873388886002896040516020016128ce9190614244565b6040516020818303038152906040526040516128ea91906142ca565b602060405180830381855afa158015612905573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061292891906142f4565b8860405160200161293f979695949392919061465e565b60405160208183030381529060405260405161295b91906142ca565b602060405180830381855afa158015612976573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612a01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129f89061444e565b60405180910390fd5b600360015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115612a3857612a37613ce0565b5b02179055507f0d0da0df275f85bed3a5fe7ae79f3559341a3f9ccd8e010133438135bda00a878884604051612a6e929190614aee565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612b56573373ffffffffffffffffffffffffffffffffffffffff166108fc8890811502906040515f60405180830381858888f19350505050158015612aec573d5f803e3d5ffd5b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f19350505050158015612b50573d5f803e3d5ffd5b50612bd2565b5f829050612b8533898373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b612bd07f0000000000000000000000000000000000000000000000000000000000000000888373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b5050505050505050565b5f6004811115612bef57612bee613ce0565b5b60015f8b81526020019081526020015f205f01601c9054906101000a900460ff166004811115612c2257612c21613ce0565b5b14612c62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c59906150ca565b60405180910390fd5b5f8811612ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c9b90615132565b60405180910390fd5b5f8711612ce6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cdd9061519a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612d54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d4b90614d8f565b60405180910390fd5b5f60038989883389898d604051602001612d74979695949392919061465e565b604051602081830303815290604052604051612d9091906142ca565b602060405180830381855afa158015612dab573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115612e0357612e02613ce0565b5b81525060015f8c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115612ebe57612ebd613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358a604051612ef5919061447b565b60405180910390a15f879050612f3933308b8d612f129190614b42565b8473ffffffffffffffffffffffffffffffffffffffff16613543909392919063ffffffff16565b5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f808383810190612fc79190614807565b90505f6003811115612fdc57612fdb613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff16600381111561301157613010613ce0565b5b14613051576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161304890615228565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff16036130c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130ba9061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161312c90614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146131a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161319e90614a00565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614613215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161320c90614a68565b60405180910390fd5b5f8511613257576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161324e90615290565b60405180910390fd5b61326481602001516134b3565b156132a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161329b90614ad0565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c6040516020016132d49796959493929190614384565b6040516020818303038152906040526040516132f091906142ca565b602060405180830381855afa15801561330b573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561335b5761335a613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156133f2576133f1613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f015160405161342c919061447b565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b61353e838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85856040516024016134f79291906152ae565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b505050565b6135bf848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161357893929190614629565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b50505050565b5f6135ef828473ffffffffffffffffffffffffffffffffffffffff1661365a90919063ffffffff16565b90505f81511415801561361357508080602001905181019061361191906152ff565b155b1561365557826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161364c919061405c565b60405180910390fd5b505050565b606061366783835f61366f565b905092915050565b6060814710156136b657306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016136ad919061405c565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516136de91906142ca565b5f6040518083038185875af1925050503d805f8114613718576040519150601f19603f3d011682016040523d82523d5f602084013e61371d565b606091505b509150915061372d868383613738565b925050509392505050565b60608261374d57613748826137c5565b6137bd565b5f825114801561377357505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156137b557836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016137ac919061405c565b60405180910390fd5b8190506137be565b5b9392505050565b5f815111156137d75780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61384e8161381a565b8114613858575f80fd5b50565b5f8135905061386981613845565b92915050565b5f6020828403121561388457613883613812565b5b5f6138918482850161385b565b91505092915050565b5f8115159050919050565b6138ae8161389a565b82525050565b5f6020820190506138c75f8301846138a5565b92915050565b5f819050919050565b6138df816138cd565b81146138e9575f80fd5b50565b5f813590506138fa816138d6565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61392982613900565b9050919050565b6139398161391f565b8114613943575f80fd5b50565b5f8135905061395481613930565b92915050565b5f819050919050565b61396c8161395a565b8114613976575f80fd5b50565b5f8135905061398781613963565b92915050565b5f805f805f805f60e0888a0312156139a8576139a7613812565b5b5f6139b58a828b016138ec565b97505060206139c68a828b01613946565b96505060406139d78a828b016138ec565b95505060606139e88a828b016138ec565b94505060806139f98a828b01613946565b93505060a0613a0a8a828b01613979565b92505060c0613a1b8a828b01613979565b91505092959891949750929550565b5f805f805f8060c08789031215613a4457613a43613812565b5b5f613a5189828a016138ec565b9650506020613a6289828a01613946565b9550506040613a7389828a016138ec565b9450506060613a8489828a016138ec565b9350506080613a9589828a01613946565b92505060a0613aa689828a01613979565b9150509295509295509295565b5f805f805f805f60e0888a031215613ace57613acd613812565b5b5f613adb8a828b016138ec565b9750506020613aec8a828b01613979565b9650506040613afd8a828b01613979565b9550506060613b0e8a828b01613946565b9450506080613b1f8a828b016138ec565b93505060a0613b308a828b016138ec565b92505060c0613b418a828b01613946565b91505092959891949750929550565b5f80fd5b5f80fd5b5f80fd5b5f8083601f840112613b7157613b70613b50565b5b8235905067ffffffffffffffff811115613b8e57613b8d613b54565b5b602083019150836001820283011115613baa57613ba9613b58565b5b9250929050565b5f805f805f60808688031215613bca57613bc9613812565b5b5f613bd788828901613946565b9550506020613be888828901613946565b9450506040613bf988828901613979565b935050606086013567ffffffffffffffff811115613c1a57613c19613816565b5b613c2688828901613b5c565b92509250509295509295909350565b613c3e8161381a565b82525050565b5f602082019050613c575f830184613c35565b92915050565b5f60208284031215613c7257613c71613812565b5b5f613c7f848285016138ec565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b613cbc81613c88565b82525050565b5f63ffffffff82169050919050565b613cda81613cc2565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60058110613d1e57613d1d613ce0565b5b50565b5f819050613d2e82613d0d565b919050565b5f613d3d82613d21565b9050919050565b613d4d81613d33565b82525050565b5f608082019050613d665f830187613cb3565b613d736020830186613cd1565b613d806040830185613cd1565b613d8d6060830184613d44565b95945050505050565b613d9f81613cc2565b8114613da9575f80fd5b50565b5f81359050613dba81613d96565b92915050565b5f805f805f805f60e0888a031215613ddb57613dda613812565b5b5f613de88a828b016138ec565b9750506020613df98a828b01613979565b9650506040613e0a8a828b01613946565b9550506060613e1b8a828b016138ec565b9450506080613e2c8a828b016138ec565b93505060a0613e3d8a828b01613dac565b92505060c0613e4e8a828b01613dac565b91505092959891949750929550565b5f8083601f840112613e7257613e71613b50565b5b8235905067ffffffffffffffff811115613e8f57613e8e613b54565b5b602083019150836020820283011115613eab57613eaa613b58565b5b9250929050565b5f805f805f805f8060a0898b031215613ece57613ecd613812565b5b5f613edb8b828c01613946565b9850506020613eec8b828c01613946565b975050604089013567ffffffffffffffff811115613f0d57613f0c613816565b5b613f198b828c01613e5d565b9650965050606089013567ffffffffffffffff811115613f3c57613f3b613816565b5b613f488b828c01613e5d565b9450945050608089013567ffffffffffffffff811115613f6b57613f6a613816565b5b613f778b828c01613b5c565b92509250509295985092959890939650565b5f805f805f805f805f6101208a8c031215613fa757613fa6613812565b5b5f613fb48c828d016138ec565b9950506020613fc58c828d01613979565b9850506040613fd68c828d01613979565b9750506060613fe78c828d01613946565b9650506080613ff88c828d01613946565b95505060a06140098c828d016138ec565b94505060c061401a8c828d016138ec565b93505060e061402b8c828d01613dac565b92505061010061403d8c828d01613dac565b9150509295985092959850929598565b6140568161391f565b82525050565b5f60208201905061406f5f83018461404d565b92915050565b6004811061408657614085613ce0565b5b50565b5f81905061409682614075565b919050565b5f6140a582614089565b9050919050565b6140b58161409b565b82525050565b5f6060820190506140ce5f830186613cb3565b6140db6020830185613cd1565b6140e860408301846140ac565b949350505050565b5f805f805f8060a0878903121561410a57614109613812565b5b5f61411789828a01613946565b965050602061412889828a01613946565b955050604061413989828a01613979565b945050606061414a89828a01613979565b935050608087013567ffffffffffffffff81111561416b5761416a613816565b5b61417789828a01613b5c565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f6141f0602a83614186565b91506141fb82614196565b604082019050919050565b5f6020820190508181035f83015261421d816141e4565b9050919050565b5f819050919050565b61423e614239826138cd565b614224565b82525050565b5f61424f828461422d565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b5f5b8381101561428f578082015181840152602081019050614274565b5f8484015250505050565b5f6142a48261425e565b6142ae8185614268565b93506142be818560208601614272565b80840191505092915050565b5f6142d5828461429a565b915081905092915050565b5f815190506142ee816138d6565b92915050565b5f6020828403121561430957614308613812565b5b5f614316848285016142e0565b91505092915050565b5f8160601b9050919050565b5f6143358261431f565b9050919050565b5f6143468261432b565b9050919050565b61435e6143598261391f565b61433c565b82525050565b5f819050919050565b61437e6143798261395a565b614364565b82525050565b5f61438f828a61434d565b60148201915061439f828961434d565b6014820191506143af828861422d565b6020820191506143bf828761422d565b6020820191506143cf828661434d565b6014820191506143df828561436d565b6020820191506143ef828461436d565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f614438601383614186565b915061444382614404565b602082019050919050565b5f6020820190508181035f8301526144658161442c565b9050919050565b614475816138cd565b82525050565b5f60208201905061448e5f83018461446c565b92915050565b61449d8161395a565b82525050565b5f82825260208201905092915050565b50565b5f6144c15f836144a3565b91506144cc826144b3565b5f82019050919050565b5f60a0820190506144e95f83018761404d565b6144f6602083018661404d565b6145036040830185614494565b6145106060830184614494565b8181036080830152614521816144b6565b905095945050505050565b5f614537828961434d565b601482019150614547828861434d565b601482019150614557828761422d565b602082019150614567828661422d565b602082019150614577828561434d565b601482019150614587828461436d565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f6145f5603883614186565b91506146008261459b565b604082019050919050565b5f6020820190508181035f830152614622816145e9565b9050919050565b5f60608201905061463c5f83018661404d565b614649602083018561404d565b6146566040830184614494565b949350505050565b5f614669828a61436d565b602082019150614679828961436d565b602082019150614689828861434d565b601482019150614699828761434d565b6014820191506146a9828661422d565b6020820191506146b9828561422d565b6020820191506146c9828461434d565b60148201915081905098975050505050505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b614728826146e2565b810181811067ffffffffffffffff82111715614747576147466146f2565b5b80604052505050565b5f614759613809565b9050614765828261471f565b919050565b5f60c0828403121561477f5761477e6146de565b5b61478960c0614750565b90505f614798848285016138ec565b5f8301525060206147ab84828501613946565b60208301525060406147bf84828501613946565b60408301525060606147d3848285016138ec565b60608301525060806147e7848285016138ec565b60808301525060a06147fb84828501613dac565b60a08301525092915050565b5f60c0828403121561481c5761481b613812565b5b5f6148298482850161476a565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f61488c602a83614186565b915061489782614832565b604082019050919050565b5f6020820190508181035f8301526148b981614880565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f6148f4601e83614186565b91506148ff826148c0565b602082019050919050565b5f6020820190508181035f830152614921816148e8565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f61495c601e83614186565b915061496782614928565b602082019050919050565b5f6020820190508181035f83015261498981614950565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f6149ea602383614186565b91506149f582614990565b604082019050919050565b5f6020820190508181035f830152614a17816149de565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f614a52601b83614186565b9150614a5d82614a1e565b602082019050919050565b5f6020820190508181035f830152614a7f81614a46565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f614aba601a83614186565b9150614ac582614a86565b602082019050919050565b5f6020820190508181035f830152614ae781614aae565b9050919050565b5f604082019050614b015f83018561446c565b614b0e602083018461446c565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614b4c8261395a565b9150614b578361395a565b9250828201905080821115614b6f57614b6e614b15565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e74206f722054616b6572417070726f7665640000000000602082015250565b5f614bcf603b83614186565b9150614bda82614b75565b604082019050919050565b5f6020820190508181035f830152614bfc81614bc3565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e74207072652d617070726f7665206c6f636b2074696d65000000602082015250565b5f614c5d603d83614186565b9150614c6882614c03565b604082019050919050565b5f6020820190508181035f830152614c8a81614c51565b9050919050565b7f54616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f614ceb602483614186565b9150614cf682614c91565b604082019050919050565b5f6020820190508181035f830152614d1881614cdf565b9050919050565b7f5265636569766572206d757374206e6f74206265207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f614d79602183614186565b9150614d8482614d1f565b604082019050919050565b5f6020820190508181035f830152614da681614d6d565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f614e07602383614186565b9150614e1282614dad565b604082019050919050565b5f6020820190508181035f830152614e3481614dfb565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e20645f8201527f6578206665650000000000000000000000000000000000000000000000000000602082015250565b5f614e95602683614186565b9150614ea082614e3b565b604082019050919050565b5f6020820190508181035f830152614ec281614e89565b9050919050565b5f614ed38261395a565b9150614ede8361395a565b9250828203905081811115614ef657614ef5614b15565b5b92915050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f614f30601d83614186565b9150614f3b82614efc565b602082019050919050565b5f6020820190508181035f830152614f5d81614f24565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f614f98601583614186565b9150614fa382614f64565b602082019050919050565b5f6020820190508181035f830152614fc581614f8c565b9050919050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520545f8201527f616b6572417070726f7665640000000000000000000000000000000000000000602082015250565b5f615026602c83614186565b915061503182614fcc565b604082019050919050565b5f6020820190508181035f8301526150538161501a565b9050919050565b7f4552433230207632207061796d656e7420697320616c726561647920696e69745f8201527f69616c697a656400000000000000000000000000000000000000000000000000602082015250565b5f6150b4602783614186565b91506150bf8261505a565b604082019050919050565b5f6020820190508181035f8301526150e1816150a8565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f61511c601783614186565b9150615127826150e8565b602082019050919050565b5f6020820190508181035f83015261514981615110565b9050919050565b7f44657820666565206d757374206e6f74206265207a65726f00000000000000005f82015250565b5f615184601883614186565b915061518f82615150565b602082019050919050565b5f6020820190508181035f8301526151b181615178565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f615212602b83614186565b915061521d826151b8565b604082019050919050565b5f6020820190508181035f83015261523f81615206565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f61527a601c83614186565b915061528582615246565b602082019050919050565b5f6020820190508181035f8301526152a78161526e565b9050919050565b5f6040820190506152c15f83018561404d565b6152ce6020830184614494565b9392505050565b6152de8161389a565b81146152e8575f80fd5b50565b5f815190506152f9816152d5565b92915050565b5f6020828403121561531457615313613812565b5b5f615321848285016152eb565b9150509291505056fea26469706673582212200d86b0f6898fb823c55626c3b02a7098bc8622606b092e0f458df6c86ce2967864736f6c63430008180033"; -pub const NFT_MAKER_SWAP_V2_BYTES: &str = "6080604052348015600e575f80fd5b50612ffd8061001c5f395ff3fe608060405234801561000f575f80fd5b50600436106100a7575f3560e01c8063b27e46fb1161006f578063b27e46fb1461015f578063bc197c811461017b578063c8d9009b146101ab578063c92cd12d146101c7578063efccb9eb146101e3578063f23a6e6114610215576100a7565b806301ffc9a7146100ab57806305ec158d146100db5780630f235fce146100f7578063150b7a02146101135780636e6bf6d214610143575b5f80fd5b6100c560048036038101906100c09190611ebc565b610245565b6040516100d29190611f01565b60405180910390f35b6100f560048036038101906100f09190611fda565b610326565b005b610111600480360381019061010c9190612077565b6105e6565b005b61012d60048036038101906101289190612161565b6108a0565b60405161013a91906121f4565b60405180910390f35b61015d60048036038101906101589190612077565b610cef565b005b61017960048036038101906101749190611fda565b610faa565b005b61019560048036038101906101909190612262565b611269565b6040516101a291906121f4565b60405180910390f35b6101c560048036038101906101c09190612077565b6112a5565b005b6101e160048036038101906101dc9190611fda565b6115ce565b005b6101fd60048036038101906101f89190612339565b6118fc565b60405161020c9392919061242f565b60405180910390f35b61022f600480360381019061022a9190612464565b611948565b60405161023c91906121f4565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061030f57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061031f575061031e82611ddc565b5b9050919050565b6001600381111561033a576103396123bc565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561036c5761036b6123bc565b5b146103ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a39061257a565b60405180910390fd5b5f600387336002896040516020016103c491906125b8565b6040516020818303038152906040526040516103e09190612624565b602060405180830381855afa1580156103fb573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061041e919061264e565b8888888860405160200161043897969594939291906126de565b6040516020818303038152906040526040516104549190612624565b602060405180830381855afa15801561046f573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146104f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f0906127a8565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561052f5761052e6123bc565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd738860405161056391906127d5565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016105ae949392919061283f565b5f604051808303815f87803b1580156105c5575f80fd5b505af11580156105d7573d5f803e3d5ffd5b50505050505050505050505050565b600160038111156105fa576105f96123bc565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561062c5761062b6123bc565b5b1461066c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106639061257a565b60405180910390fd5b5f600386338787878760405160200161068a96959493929190612895565b6040516020818303038152906040526040516106a69190612624565b602060405180830381855afa1580156106c1573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461074b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610742906127a8565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156107b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ad90612974565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff021916908360038111156107ec576107eb6123bc565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad192190728760405161082091906127d5565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b815260040161086993929190612992565b5f604051808303815f87803b158015610880575f80fd5b505af1158015610892573d5f803e3d5ffd5b505050505050505050505050565b5f8083838101906108b19190612b1a565b90505f60038111156108c6576108c56123bc565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff1660038111156108fb576108fa6123bc565b5b1461093b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093290612bb5565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff16036109ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109a490612c1d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610a1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1690612c85565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8890612d13565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610aff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af690612d7b565b60405180910390fd5b610b0c8160200151611e45565b15610b4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4390612de3565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610b7a96959493929190612895565b604051602081830303815290604052604051610b969190612624565b602060405180830381855afa158015610bb1573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115610c0157610c006123bc565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115610c9857610c976123bc565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051610cd291906127d5565b60405180910390a163150b7a0260e01b9250505095945050505050565b60016003811115610d0357610d026123bc565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff166003811115610d3557610d346123bc565b5b14610d75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6c9061257a565b60405180910390fd5b5f60038633600288604051602001610d8d91906125b8565b604051602081830303815290604052604051610da99190612624565b602060405180830381855afa158015610dc4573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610de7919061264e565b878787604051602001610dff96959493929190612895565b604051602081830303815290604052604051610e1b9190612624565b602060405180830381855afa158015610e36573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610ec0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb7906127a8565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610ef657610ef56123bc565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051610f2a91906127d5565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610f7393929190612992565b5f604051808303815f87803b158015610f8a575f80fd5b505af1158015610f9c573d5f803e3d5ffd5b505050505050505050505050565b60016003811115610fbe57610fbd6123bc565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115610ff057610fef6123bc565b5b14611030576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110279061257a565b60405180910390fd5b5f60038733888888888860405160200161105097969594939291906126de565b60405160208183030381529060405260405161106c9190612624565b602060405180830381855afa158015611087573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611111576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611108906127a8565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff1642101561117c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117390612974565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156111b2576111b16123bc565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad19219072886040516111e691906127d5565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b8152600401611231949392919061283f565b5f604051808303815f87803b158015611248575f80fd5b505af115801561125a573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129c90612e4b565b60405180910390fd5b600160038111156112b9576112b86123bc565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff1660038111156112eb576112ea6123bc565b5b1461132b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113229061257a565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139090612eb3565b60405180910390fd5b5f60033387876002886040516020016113b291906125b8565b6040516020818303038152906040526040516113ce9190612624565b602060405180830381855afa1580156113e9573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061140c919061264e565b878760405160200161142396959493929190612895565b60405160208183030381529060405260405161143f9190612624565b602060405180830381855afa15801561145a573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146114e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114db906127a8565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561151a576115196123bc565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161154e91906127d5565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b815260040161159793929190612992565b5f604051808303815f87803b1580156115ae575f80fd5b505af11580156115c0573d5f803e3d5ffd5b505050505050505050505050565b600160038111156115e2576115e16123bc565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115611614576116136123bc565b5b14611654576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164b9061257a565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b990612eb3565b60405180910390fd5b5f60033388886002896040516020016116db91906125b8565b6040516020818303038152906040526040516116f79190612624565b602060405180830381855afa158015611712573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190611735919061264e565b88888860405160200161174e97969594939291906126de565b60405160208183030381529060405260405161176a9190612624565b602060405180830381855afa158015611785573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461180f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611806906127a8565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff02191690836003811115611845576118446123bc565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08860405161187991906127d5565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016118c4949392919061283f565b5f604051808303815f87803b1580156118db575f80fd5b505af11580156118ed573d5f803e3d5ffd5b50505050505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f8083838101906119599190612b1a565b90505f600381111561196e5761196d6123bc565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff1660038111156119a3576119a26123bc565b5b146119e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119da90612f41565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603611a55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4c90612c1d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603611ac7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611abe90612c85565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611b39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3090612d13565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614611ba7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9e90612d7b565b60405180910390fd5b5f8511611be9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be090612fa9565b60405180910390fd5b611bf68160200151611e45565b15611c36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2d90612de3565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c604051602001611c6697969594939291906126de565b604051602081830303815290604052604051611c829190612624565b602060405180830381855afa158015611c9d573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115611ced57611cec6123bc565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115611d8457611d836123bc565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051611dbe91906127d5565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611e9b81611e67565b8114611ea5575f80fd5b50565b5f81359050611eb681611e92565b92915050565b5f60208284031215611ed157611ed0611e5f565b5b5f611ede84828501611ea8565b91505092915050565b5f8115159050919050565b611efb81611ee7565b82525050565b5f602082019050611f145f830184611ef2565b92915050565b5f819050919050565b611f2c81611f1a565b8114611f36575f80fd5b50565b5f81359050611f4781611f23565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611f7682611f4d565b9050919050565b611f8681611f6c565b8114611f90575f80fd5b50565b5f81359050611fa181611f7d565b92915050565b5f819050919050565b611fb981611fa7565b8114611fc3575f80fd5b50565b5f81359050611fd481611fb0565b92915050565b5f805f805f805f60e0888a031215611ff557611ff4611e5f565b5b5f6120028a828b01611f39565b97505060206120138a828b01611f93565b96505060406120248a828b01611f39565b95505060606120358a828b01611f39565b94505060806120468a828b01611f93565b93505060a06120578a828b01611fc6565b92505060c06120688a828b01611fc6565b91505092959891949750929550565b5f805f805f8060c0878903121561209157612090611e5f565b5b5f61209e89828a01611f39565b96505060206120af89828a01611f93565b95505060406120c089828a01611f39565b94505060606120d189828a01611f39565b93505060806120e289828a01611f93565b92505060a06120f389828a01611fc6565b9150509295509295509295565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261212157612120612100565b5b8235905067ffffffffffffffff81111561213e5761213d612104565b5b60208301915083600182028301111561215a57612159612108565b5b9250929050565b5f805f805f6080868803121561217a57612179611e5f565b5b5f61218788828901611f93565b955050602061219888828901611f93565b94505060406121a988828901611fc6565b935050606086013567ffffffffffffffff8111156121ca576121c9611e63565b5b6121d68882890161210c565b92509250509295509295909350565b6121ee81611e67565b82525050565b5f6020820190506122075f8301846121e5565b92915050565b5f8083601f84011261222257612221612100565b5b8235905067ffffffffffffffff81111561223f5761223e612104565b5b60208301915083602082028301111561225b5761225a612108565b5b9250929050565b5f805f805f805f8060a0898b03121561227e5761227d611e5f565b5b5f61228b8b828c01611f93565b985050602061229c8b828c01611f93565b975050604089013567ffffffffffffffff8111156122bd576122bc611e63565b5b6122c98b828c0161220d565b9650965050606089013567ffffffffffffffff8111156122ec576122eb611e63565b5b6122f88b828c0161220d565b9450945050608089013567ffffffffffffffff81111561231b5761231a611e63565b5b6123278b828c0161210c565b92509250509295985092959890939650565b5f6020828403121561234e5761234d611e5f565b5b5f61235b84828501611f39565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b61239881612364565b82525050565b5f63ffffffff82169050919050565b6123b68161239e565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600481106123fa576123f96123bc565b5b50565b5f81905061240a826123e9565b919050565b5f612419826123fd565b9050919050565b6124298161240f565b82525050565b5f6060820190506124425f83018661238f565b61244f60208301856123ad565b61245c6040830184612420565b949350505050565b5f805f805f8060a0878903121561247e5761247d611e5f565b5b5f61248b89828a01611f93565b965050602061249c89828a01611f93565b95505060406124ad89828a01611fc6565b94505060606124be89828a01611fc6565b935050608087013567ffffffffffffffff8111156124df576124de611e63565b5b6124eb89828a0161210c565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f612564602a836124fa565b915061256f8261250a565b604082019050919050565b5f6020820190508181035f83015261259181612558565b9050919050565b5f819050919050565b6125b26125ad82611f1a565b612598565b82525050565b5f6125c382846125a1565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6125fe826125d2565b61260881856125dc565b93506126188185602086016125e6565b80840191505092915050565b5f61262f82846125f4565b915081905092915050565b5f8151905061264881611f23565b92915050565b5f6020828403121561266357612662611e5f565b5b5f6126708482850161263a565b91505092915050565b5f8160601b9050919050565b5f61268f82612679565b9050919050565b5f6126a082612685565b9050919050565b6126b86126b382611f6c565b612696565b82525050565b5f819050919050565b6126d86126d382611fa7565b6126be565b82525050565b5f6126e9828a6126a7565b6014820191506126f982896126a7565b60148201915061270982886125a1565b60208201915061271982876125a1565b60208201915061272982866126a7565b60148201915061273982856126c7565b60208201915061274982846126c7565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f6127926013836124fa565b915061279d8261275e565b602082019050919050565b5f6020820190508181035f8301526127bf81612786565b9050919050565b6127cf81611f1a565b82525050565b5f6020820190506127e85f8301846127c6565b92915050565b6127f781611f6c565b82525050565b61280681611fa7565b82525050565b5f82825260208201905092915050565b50565b5f61282a5f8361280c565b91506128358261281c565b5f82019050919050565b5f60a0820190506128525f8301876127ee565b61285f60208301866127ee565b61286c60408301856127fd565b61287960608301846127fd565b818103608083015261288a8161281f565b905095945050505050565b5f6128a082896126a7565b6014820191506128b082886126a7565b6014820191506128c082876125a1565b6020820191506128d082866125a1565b6020820191506128e082856126a7565b6014820191506128f082846126c7565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f61295e6038836124fa565b915061296982612904565b604082019050919050565b5f6020820190508181035f83015261298b81612952565b9050919050565b5f6060820190506129a55f8301866127ee565b6129b260208301856127ee565b6129bf60408301846127fd565b949350505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612a11826129cb565b810181811067ffffffffffffffff82111715612a3057612a2f6129db565b5b80604052505050565b5f612a42611e56565b9050612a4e8282612a08565b919050565b612a5c8161239e565b8114612a66575f80fd5b50565b5f81359050612a7781612a53565b92915050565b5f60c08284031215612a9257612a916129c7565b5b612a9c60c0612a39565b90505f612aab84828501611f39565b5f830152506020612abe84828501611f93565b6020830152506040612ad284828501611f93565b6040830152506060612ae684828501611f39565b6060830152506080612afa84828501611f39565b60808301525060a0612b0e84828501612a69565b60a08301525092915050565b5f60c08284031215612b2f57612b2e611e5f565b5b5f612b3c84828501612a7d565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f612b9f602a836124fa565b9150612baa82612b45565b604082019050919050565b5f6020820190508181035f830152612bcc81612b93565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612c07601e836124fa565b9150612c1282612bd3565b602082019050919050565b5f6020820190508181035f830152612c3481612bfb565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612c6f601e836124fa565b9150612c7a82612c3b565b602082019050919050565b5f6020820190508181035f830152612c9c81612c63565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f612cfd6023836124fa565b9150612d0882612ca3565b604082019050919050565b5f6020820190508181035f830152612d2a81612cf1565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f612d65601b836124fa565b9150612d7082612d31565b602082019050919050565b5f6020820190508181035f830152612d9281612d59565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f612dcd601a836124fa565b9150612dd882612d99565b602082019050919050565b5f6020820190508181035f830152612dfa81612dc1565b9050919050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f612e35601d836124fa565b9150612e4082612e01565b602082019050919050565b5f6020820190508181035f830152612e6281612e29565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f612e9d6015836124fa565b9150612ea882612e69565b602082019050919050565b5f6020820190508181035f830152612eca81612e91565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f612f2b602b836124fa565b9150612f3682612ed1565b604082019050919050565b5f6020820190508181035f830152612f5881612f1f565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f612f93601c836124fa565b9150612f9e82612f5f565b602082019050919050565b5f6020820190508181035f830152612fc081612f87565b905091905056fea2646970667358221220c066835d4b6ab57c60e10e6f680a4c26f0d64160b65fc0650c3d6e59f29798a164736f6c63430008190033"; +pub const NFT_MAKER_SWAP_V2_BYTES: &str = "6080604052348015600e575f80fd5b50612ffd8061001c5f395ff3fe608060405234801561000f575f80fd5b50600436106100a7575f3560e01c8063b27e46fb1161006f578063b27e46fb1461015f578063bc197c811461017b578063c8d9009b146101ab578063c92cd12d146101c7578063efccb9eb146101e3578063f23a6e6114610215576100a7565b806301ffc9a7146100ab57806305ec158d146100db5780630f235fce146100f7578063150b7a02146101135780636e6bf6d214610143575b5f80fd5b6100c560048036038101906100c09190611ebc565b610245565b6040516100d29190611f01565b60405180910390f35b6100f560048036038101906100f09190611fda565b610326565b005b610111600480360381019061010c9190612077565b6105e6565b005b61012d60048036038101906101289190612161565b6108a0565b60405161013a91906121f4565b60405180910390f35b61015d60048036038101906101589190612077565b610cef565b005b61017960048036038101906101749190611fda565b610faa565b005b61019560048036038101906101909190612262565b611269565b6040516101a291906121f4565b60405180910390f35b6101c560048036038101906101c09190612077565b6112a5565b005b6101e160048036038101906101dc9190611fda565b6115ce565b005b6101fd60048036038101906101f89190612339565b6118fc565b60405161020c9392919061242f565b60405180910390f35b61022f600480360381019061022a9190612464565b611948565b60405161023c91906121f4565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061030f57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061031f575061031e82611ddc565b5b9050919050565b6001600381111561033a576103396123bc565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561036c5761036b6123bc565b5b146103ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a39061257a565b60405180910390fd5b5f600387336002896040516020016103c491906125b8565b6040516020818303038152906040526040516103e09190612624565b602060405180830381855afa1580156103fb573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061041e919061264e565b8888888860405160200161043897969594939291906126de565b6040516020818303038152906040526040516104549190612624565b602060405180830381855afa15801561046f573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146104f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f0906127a8565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561052f5761052e6123bc565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd738860405161056391906127d5565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016105ae949392919061283f565b5f604051808303815f87803b1580156105c5575f80fd5b505af11580156105d7573d5f803e3d5ffd5b50505050505050505050505050565b600160038111156105fa576105f96123bc565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561062c5761062b6123bc565b5b1461066c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106639061257a565b60405180910390fd5b5f600386338787878760405160200161068a96959493929190612895565b6040516020818303038152906040526040516106a69190612624565b602060405180830381855afa1580156106c1573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461074b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610742906127a8565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156107b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ad90612974565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff021916908360038111156107ec576107eb6123bc565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad192190728760405161082091906127d5565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b815260040161086993929190612992565b5f604051808303815f87803b158015610880575f80fd5b505af1158015610892573d5f803e3d5ffd5b505050505050505050505050565b5f8083838101906108b19190612b1a565b90505f60038111156108c6576108c56123bc565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff1660038111156108fb576108fa6123bc565b5b1461093b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093290612bb5565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff16036109ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109a490612c1d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610a1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1690612c85565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8890612d13565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610aff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af690612d7b565b60405180910390fd5b610b0c8160200151611e45565b15610b4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4390612de3565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610b7a96959493929190612895565b604051602081830303815290604052604051610b969190612624565b602060405180830381855afa158015610bb1573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115610c0157610c006123bc565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115610c9857610c976123bc565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051610cd291906127d5565b60405180910390a163150b7a0260e01b9250505095945050505050565b60016003811115610d0357610d026123bc565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff166003811115610d3557610d346123bc565b5b14610d75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6c9061257a565b60405180910390fd5b5f60038633600288604051602001610d8d91906125b8565b604051602081830303815290604052604051610da99190612624565b602060405180830381855afa158015610dc4573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610de7919061264e565b878787604051602001610dff96959493929190612895565b604051602081830303815290604052604051610e1b9190612624565b602060405180830381855afa158015610e36573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610ec0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb7906127a8565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610ef657610ef56123bc565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051610f2a91906127d5565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610f7393929190612992565b5f604051808303815f87803b158015610f8a575f80fd5b505af1158015610f9c573d5f803e3d5ffd5b505050505050505050505050565b60016003811115610fbe57610fbd6123bc565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115610ff057610fef6123bc565b5b14611030576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110279061257a565b60405180910390fd5b5f60038733888888888860405160200161105097969594939291906126de565b60405160208183030381529060405260405161106c9190612624565b602060405180830381855afa158015611087573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611111576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611108906127a8565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff1642101561117c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117390612974565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156111b2576111b16123bc565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad19219072886040516111e691906127d5565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b8152600401611231949392919061283f565b5f604051808303815f87803b158015611248575f80fd5b505af115801561125a573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129c90612e4b565b60405180910390fd5b600160038111156112b9576112b86123bc565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff1660038111156112eb576112ea6123bc565b5b1461132b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113229061257a565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139090612eb3565b60405180910390fd5b5f60033387876002886040516020016113b291906125b8565b6040516020818303038152906040526040516113ce9190612624565b602060405180830381855afa1580156113e9573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061140c919061264e565b878760405160200161142396959493929190612895565b60405160208183030381529060405260405161143f9190612624565b602060405180830381855afa15801561145a573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146114e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114db906127a8565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561151a576115196123bc565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161154e91906127d5565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b815260040161159793929190612992565b5f604051808303815f87803b1580156115ae575f80fd5b505af11580156115c0573d5f803e3d5ffd5b505050505050505050505050565b600160038111156115e2576115e16123bc565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115611614576116136123bc565b5b14611654576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164b9061257a565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b990612eb3565b60405180910390fd5b5f60033388886002896040516020016116db91906125b8565b6040516020818303038152906040526040516116f79190612624565b602060405180830381855afa158015611712573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190611735919061264e565b88888860405160200161174e97969594939291906126de565b60405160208183030381529060405260405161176a9190612624565b602060405180830381855afa158015611785573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461180f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611806906127a8565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff02191690836003811115611845576118446123bc565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08860405161187991906127d5565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016118c4949392919061283f565b5f604051808303815f87803b1580156118db575f80fd5b505af11580156118ed573d5f803e3d5ffd5b50505050505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f8083838101906119599190612b1a565b90505f600381111561196e5761196d6123bc565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff1660038111156119a3576119a26123bc565b5b146119e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119da90612f41565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603611a55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4c90612c1d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603611ac7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611abe90612c85565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611b39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3090612d13565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614611ba7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9e90612d7b565b60405180910390fd5b5f8511611be9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be090612fa9565b60405180910390fd5b611bf68160200151611e45565b15611c36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2d90612de3565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c604051602001611c6697969594939291906126de565b604051602081830303815290604052604051611c829190612624565b602060405180830381855afa158015611c9d573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115611ced57611cec6123bc565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115611d8457611d836123bc565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051611dbe91906127d5565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611e9b81611e67565b8114611ea5575f80fd5b50565b5f81359050611eb681611e92565b92915050565b5f60208284031215611ed157611ed0611e5f565b5b5f611ede84828501611ea8565b91505092915050565b5f8115159050919050565b611efb81611ee7565b82525050565b5f602082019050611f145f830184611ef2565b92915050565b5f819050919050565b611f2c81611f1a565b8114611f36575f80fd5b50565b5f81359050611f4781611f23565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611f7682611f4d565b9050919050565b611f8681611f6c565b8114611f90575f80fd5b50565b5f81359050611fa181611f7d565b92915050565b5f819050919050565b611fb981611fa7565b8114611fc3575f80fd5b50565b5f81359050611fd481611fb0565b92915050565b5f805f805f805f60e0888a031215611ff557611ff4611e5f565b5b5f6120028a828b01611f39565b97505060206120138a828b01611f93565b96505060406120248a828b01611f39565b95505060606120358a828b01611f39565b94505060806120468a828b01611f93565b93505060a06120578a828b01611fc6565b92505060c06120688a828b01611fc6565b91505092959891949750929550565b5f805f805f8060c0878903121561209157612090611e5f565b5b5f61209e89828a01611f39565b96505060206120af89828a01611f93565b95505060406120c089828a01611f39565b94505060606120d189828a01611f39565b93505060806120e289828a01611f93565b92505060a06120f389828a01611fc6565b9150509295509295509295565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261212157612120612100565b5b8235905067ffffffffffffffff81111561213e5761213d612104565b5b60208301915083600182028301111561215a57612159612108565b5b9250929050565b5f805f805f6080868803121561217a57612179611e5f565b5b5f61218788828901611f93565b955050602061219888828901611f93565b94505060406121a988828901611fc6565b935050606086013567ffffffffffffffff8111156121ca576121c9611e63565b5b6121d68882890161210c565b92509250509295509295909350565b6121ee81611e67565b82525050565b5f6020820190506122075f8301846121e5565b92915050565b5f8083601f84011261222257612221612100565b5b8235905067ffffffffffffffff81111561223f5761223e612104565b5b60208301915083602082028301111561225b5761225a612108565b5b9250929050565b5f805f805f805f8060a0898b03121561227e5761227d611e5f565b5b5f61228b8b828c01611f93565b985050602061229c8b828c01611f93565b975050604089013567ffffffffffffffff8111156122bd576122bc611e63565b5b6122c98b828c0161220d565b9650965050606089013567ffffffffffffffff8111156122ec576122eb611e63565b5b6122f88b828c0161220d565b9450945050608089013567ffffffffffffffff81111561231b5761231a611e63565b5b6123278b828c0161210c565b92509250509295985092959890939650565b5f6020828403121561234e5761234d611e5f565b5b5f61235b84828501611f39565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b61239881612364565b82525050565b5f63ffffffff82169050919050565b6123b68161239e565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600481106123fa576123f96123bc565b5b50565b5f81905061240a826123e9565b919050565b5f612419826123fd565b9050919050565b6124298161240f565b82525050565b5f6060820190506124425f83018661238f565b61244f60208301856123ad565b61245c6040830184612420565b949350505050565b5f805f805f8060a0878903121561247e5761247d611e5f565b5b5f61248b89828a01611f93565b965050602061249c89828a01611f93565b95505060406124ad89828a01611fc6565b94505060606124be89828a01611fc6565b935050608087013567ffffffffffffffff8111156124df576124de611e63565b5b6124eb89828a0161210c565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f612564602a836124fa565b915061256f8261250a565b604082019050919050565b5f6020820190508181035f83015261259181612558565b9050919050565b5f819050919050565b6125b26125ad82611f1a565b612598565b82525050565b5f6125c382846125a1565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6125fe826125d2565b61260881856125dc565b93506126188185602086016125e6565b80840191505092915050565b5f61262f82846125f4565b915081905092915050565b5f8151905061264881611f23565b92915050565b5f6020828403121561266357612662611e5f565b5b5f6126708482850161263a565b91505092915050565b5f8160601b9050919050565b5f61268f82612679565b9050919050565b5f6126a082612685565b9050919050565b6126b86126b382611f6c565b612696565b82525050565b5f819050919050565b6126d86126d382611fa7565b6126be565b82525050565b5f6126e9828a6126a7565b6014820191506126f982896126a7565b60148201915061270982886125a1565b60208201915061271982876125a1565b60208201915061272982866126a7565b60148201915061273982856126c7565b60208201915061274982846126c7565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f6127926013836124fa565b915061279d8261275e565b602082019050919050565b5f6020820190508181035f8301526127bf81612786565b9050919050565b6127cf81611f1a565b82525050565b5f6020820190506127e85f8301846127c6565b92915050565b6127f781611f6c565b82525050565b61280681611fa7565b82525050565b5f82825260208201905092915050565b50565b5f61282a5f8361280c565b91506128358261281c565b5f82019050919050565b5f60a0820190506128525f8301876127ee565b61285f60208301866127ee565b61286c60408301856127fd565b61287960608301846127fd565b818103608083015261288a8161281f565b905095945050505050565b5f6128a082896126a7565b6014820191506128b082886126a7565b6014820191506128c082876125a1565b6020820191506128d082866125a1565b6020820191506128e082856126a7565b6014820191506128f082846126c7565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f61295e6038836124fa565b915061296982612904565b604082019050919050565b5f6020820190508181035f83015261298b81612952565b9050919050565b5f6060820190506129a55f8301866127ee565b6129b260208301856127ee565b6129bf60408301846127fd565b949350505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612a11826129cb565b810181811067ffffffffffffffff82111715612a3057612a2f6129db565b5b80604052505050565b5f612a42611e56565b9050612a4e8282612a08565b919050565b612a5c8161239e565b8114612a66575f80fd5b50565b5f81359050612a7781612a53565b92915050565b5f60c08284031215612a9257612a916129c7565b5b612a9c60c0612a39565b90505f612aab84828501611f39565b5f830152506020612abe84828501611f93565b6020830152506040612ad284828501611f93565b6040830152506060612ae684828501611f39565b6060830152506080612afa84828501611f39565b60808301525060a0612b0e84828501612a69565b60a08301525092915050565b5f60c08284031215612b2f57612b2e611e5f565b5b5f612b3c84828501612a7d565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f612b9f602a836124fa565b9150612baa82612b45565b604082019050919050565b5f6020820190508181035f830152612bcc81612b93565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612c07601e836124fa565b9150612c1282612bd3565b602082019050919050565b5f6020820190508181035f830152612c3481612bfb565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612c6f601e836124fa565b9150612c7a82612c3b565b602082019050919050565b5f6020820190508181035f830152612c9c81612c63565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f612cfd6023836124fa565b9150612d0882612ca3565b604082019050919050565b5f6020820190508181035f830152612d2a81612cf1565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f612d65601b836124fa565b9150612d7082612d31565b602082019050919050565b5f6020820190508181035f830152612d9281612d59565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f612dcd601a836124fa565b9150612dd882612d99565b602082019050919050565b5f6020820190508181035f830152612dfa81612dc1565b9050919050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f612e35601d836124fa565b9150612e4082612e01565b602082019050919050565b5f6020820190508181035f830152612e6281612e29565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f612e9d6015836124fa565b9150612ea882612e69565b602082019050919050565b5f6020820190508181035f830152612eca81612e91565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f612f2b602b836124fa565b9150612f3682612ed1565b604082019050919050565b5f6020820190508181035f830152612f5881612f1f565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f612f93601c836124fa565b9150612f9e82612f5f565b602082019050919050565b5f6020820190508181035f830152612fc081612f87565b905091905056fea26469706673582212204e239c256ffaf5624f6d55ae2e9f8afd626e0e129a36ff33221d4b2fe58f6b5a64736f6c63430008190033"; pub trait CoinDockerOps { fn rpc_client(&self) -> &UtxoRpcClientEnum; @@ -375,7 +375,13 @@ pub fn utxo_asset_docker_node<'a>(docker: &'a Cli, ticker: &'static str, port: u pub fn geth_docker_node<'a>(docker: &'a Cli, ticker: &'static str, port: u16) -> DockerNode<'a> { let image = GenericImage::new(GETH_DOCKER_IMAGE, "stable"); - let args = vec!["--dev".into(), "--http".into(), "--http.addr=0.0.0.0".into()]; + let args = vec![ + "--dev".into(), + "--http".into(), + "--http.addr=0.0.0.0".into(), + "--dev.period=0".into(), + "--verbosity=4".into(), + ]; let image = RunnableImage::from((image, args)).with_mapped_port((port, port)); let container = docker.run(image); DockerNode { @@ -1111,6 +1117,8 @@ async fn get_current_gas_limit(web3: &Web3) { pub fn init_geth_node() { unsafe { block_on(get_current_gas_limit(&GETH_WEB3)); + let gas_price = block_on(GETH_WEB3.eth().gas_price()).unwrap(); + log!("Current gas price: {:?}", gas_price); let accounts = block_on(GETH_WEB3.eth().accounts()).unwrap(); GETH_ACCOUNT = accounts[0]; log!("GETH ACCOUNT {:?}", GETH_ACCOUNT); @@ -1227,56 +1235,13 @@ pub fn init_geth_node() { thread::sleep(Duration::from_millis(100)); } - let name = Token::String("MyNFT".into()); - let symbol = Token::String("MNFT".into()); - let params = ethabi::encode(&[name, symbol]); - let erc721_data = format!("{}{}", ERC721_TEST_TOKEN_BYTES, hex::encode(params)); - - let tx_request_deploy_erc721 = TransactionRequest { - from: GETH_ACCOUNT, - to: None, - gas: None, - gas_price: None, - value: None, - data: Some(hex::decode(erc721_data).unwrap().into()), - nonce: None, - condition: None, - transaction_type: None, - access_list: None, - max_fee_per_gas: None, - max_priority_fee_per_gas: None, - }; - let deploy_erc721_tx_hash = block_on(GETH_WEB3.eth().send_transaction(tx_request_deploy_erc721)).unwrap(); - log!("Sent ERC721 deploy transaction {:?}", deploy_erc721_tx_hash); - - loop { - let deploy_erc721_tx_receipt = match block_on(GETH_WEB3.eth().transaction_receipt(deploy_erc721_tx_hash)) { - Ok(receipt) => receipt, - Err(_) => { - thread::sleep(Duration::from_millis(100)); - continue; - }, - }; - - if let Some(receipt) = deploy_erc721_tx_receipt { - GETH_ERC721_CONTRACT = receipt.contract_address.unwrap(); - log!("GETH_ERC721_CONTRACT {:?}", GETH_ERC721_CONTRACT); - break; - } - thread::sleep(Duration::from_millis(100)); - } - - let uri = Token::String("MyNFTUri".into()); - let params = ethabi::encode(&[uri]); - let erc1155_data = format!("{}{}", ERC1155_TEST_TOKEN_BYTES, hex::encode(params)); - - let tx_request_deploy_erc1155 = TransactionRequest { + let tx_request_deploy_nft_maker_swap_v2_contract = TransactionRequest { from: GETH_ACCOUNT, to: None, gas: None, gas_price: None, value: None, - data: Some(hex::decode(erc1155_data).unwrap().into()), + data: Some(hex::decode(NFT_MAKER_SWAP_V2_BYTES).unwrap().into()), nonce: None, condition: None, transaction_type: None, @@ -1284,22 +1249,34 @@ pub fn init_geth_node() { max_fee_per_gas: None, max_priority_fee_per_gas: None, }; - let deploy_erc1155_tx_hash = block_on(GETH_WEB3.eth().send_transaction(tx_request_deploy_erc1155)).unwrap(); - log!("Sent ERC1155 deploy transaction {:?}", deploy_erc721_tx_hash); + let deploy_nft_maker_swap_v2_tx_hash = block_on( + GETH_WEB3 + .eth() + .send_transaction(tx_request_deploy_nft_maker_swap_v2_contract), + ) + .unwrap(); + log!( + "Sent deploy nft maker swap v2 contract transaction {:?}", + deploy_nft_maker_swap_v2_tx_hash + ); loop { - let deploy_erc1155_tx_receipt = match block_on(GETH_WEB3.eth().transaction_receipt(deploy_erc1155_tx_hash)) - { - Ok(receipt) => receipt, - Err(_) => { - thread::sleep(Duration::from_millis(100)); - continue; - }, - }; + let deploy_nft_maker_swap_v2_tx_receipt = + match block_on(GETH_WEB3.eth().transaction_receipt(deploy_nft_maker_swap_v2_tx_hash)) { + Ok(receipt) => receipt, + Err(_) => { + thread::sleep(Duration::from_millis(100)); + continue; + }, + }; - if let Some(receipt) = deploy_erc1155_tx_receipt { - GETH_ERC1155_CONTRACT = receipt.contract_address.unwrap(); - log!("GETH_ERC1155_CONTRACT {:?}", GETH_ERC1155_CONTRACT); + if let Some(receipt) = deploy_nft_maker_swap_v2_tx_receipt { + GETH_NFT_MAKER_SWAP_V2 = receipt.contract_address.unwrap(); + log!( + "GETH_NFT_MAKER_SWAP_V2 {:?}, receipt.status {:?}", + GETH_NFT_MAKER_SWAP_V2, + receipt.status + ); break; } thread::sleep(Duration::from_millis(100)); @@ -1349,13 +1326,18 @@ pub fn init_geth_node() { thread::sleep(Duration::from_millis(100)); } - let tx_request_deploy_nft_maker_swap_v2_contract = TransactionRequest { + let name = Token::String("MyNFT".into()); + let symbol = Token::String("MNFT".into()); + let params = ethabi::encode(&[name, symbol]); + let erc721_data = format!("{}{}", ERC721_TEST_TOKEN_BYTES, hex::encode(params)); + + let tx_request_deploy_erc721 = TransactionRequest { from: GETH_ACCOUNT, to: None, gas: None, gas_price: None, value: None, - data: Some(hex::decode(NFT_MAKER_SWAP_V2_BYTES).unwrap().into()), + data: Some(hex::decode(erc721_data).unwrap().into()), nonce: None, condition: None, transaction_type: None, @@ -1363,34 +1345,60 @@ pub fn init_geth_node() { max_fee_per_gas: None, max_priority_fee_per_gas: None, }; - let deploy_nft_maker_swap_v2_tx_hash = block_on( - GETH_WEB3 - .eth() - .send_transaction(tx_request_deploy_nft_maker_swap_v2_contract), - ) - .unwrap(); - log!( - "Sent deploy nft swap contract transaction {:?}", - deploy_nft_maker_swap_v2_tx_hash - ); + let deploy_erc721_tx_hash = block_on(GETH_WEB3.eth().send_transaction(tx_request_deploy_erc721)).unwrap(); + log!("Sent ERC721 deploy transaction {:?}", deploy_erc721_tx_hash); loop { - let deploy_nft_maker_swap_v2_tx_receipt = - match block_on(GETH_WEB3.eth().transaction_receipt(deploy_nft_maker_swap_v2_tx_hash)) { - Ok(receipt) => receipt, - Err(_) => { - thread::sleep(Duration::from_millis(100)); - continue; - }, - }; + let deploy_erc721_tx_receipt = match block_on(GETH_WEB3.eth().transaction_receipt(deploy_erc721_tx_hash)) { + Ok(receipt) => receipt, + Err(_) => { + thread::sleep(Duration::from_millis(100)); + continue; + }, + }; - if let Some(receipt) = deploy_nft_maker_swap_v2_tx_receipt { - GETH_NFT_MAKER_SWAP_V2 = receipt.contract_address.unwrap(); - log!( - "GETH_NFT_MAKER_SWAP_V2 {:?}, receipt.status {:?}", - GETH_NFT_MAKER_SWAP_V2, - receipt.status - ); + if let Some(receipt) = deploy_erc721_tx_receipt { + GETH_ERC721_CONTRACT = receipt.contract_address.unwrap(); + log!("GETH_ERC721_CONTRACT {:?}", GETH_ERC721_CONTRACT); + break; + } + thread::sleep(Duration::from_millis(100)); + } + + let uri = Token::String("MyNFTUri".into()); + let params = ethabi::encode(&[uri]); + let erc1155_data = format!("{}{}", ERC1155_TEST_TOKEN_BYTES, hex::encode(params)); + + let tx_request_deploy_erc1155 = TransactionRequest { + from: GETH_ACCOUNT, + to: None, + gas: None, + gas_price: None, + value: None, + data: Some(hex::decode(erc1155_data).unwrap().into()), + nonce: None, + condition: None, + transaction_type: None, + access_list: None, + max_fee_per_gas: None, + max_priority_fee_per_gas: None, + }; + let deploy_erc1155_tx_hash = block_on(GETH_WEB3.eth().send_transaction(tx_request_deploy_erc1155)).unwrap(); + log!("Sent ERC1155 deploy transaction {:?}", deploy_erc721_tx_hash); + + loop { + let deploy_erc1155_tx_receipt = match block_on(GETH_WEB3.eth().transaction_receipt(deploy_erc1155_tx_hash)) + { + Ok(receipt) => receipt, + Err(_) => { + thread::sleep(Duration::from_millis(100)); + continue; + }, + }; + + if let Some(receipt) = deploy_erc1155_tx_receipt { + GETH_ERC1155_CONTRACT = receipt.contract_address.unwrap(); + log!("GETH_ERC1155_CONTRACT {:?}", GETH_ERC1155_CONTRACT); break; } thread::sleep(Duration::from_millis(100)); diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 6a1f179c5f..4151c334d8 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -31,6 +31,7 @@ pub fn geth_account() -> Address { unsafe { GETH_ACCOUNT } } /// GETH_SWAP_CONTRACT is set once during initialization before tests start pub fn swap_contract() -> Address { unsafe { GETH_SWAP_CONTRACT } } +#[allow(dead_code)] /// # Safety /// /// GETH_NFT_SWAP_CONTRACT is set once during initialization before tests start @@ -140,7 +141,7 @@ pub(crate) fn mint_erc721(to_addr: Address, token_id: U256) { ); } -fn erc712_owner(token_id: U256) -> Address { +pub(crate) fn erc712_owner(token_id: U256) -> Address { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc721_contract = Contract::from_json(GETH_WEB3.eth(), erc721_contract(), ERC721_TEST_ABI.as_bytes()).unwrap(); block_on(erc721_contract.query("ownerOf", Token::Uint(token_id), None, Options::default(), None)).unwrap() @@ -182,7 +183,7 @@ pub(crate) fn mint_erc1155(to_addr: Address, token_id: U256, amount: U256) { ); } -fn erc1155_balance(wallet_addr: Address, token_id: U256) -> U256 { +pub(crate) fn erc1155_balance(wallet_addr: Address, token_id: U256) -> U256 { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc1155_contract = Contract::from_json(GETH_WEB3.eth(), erc1155_contract(), ERC1155_TEST_ABI.as_bytes()).unwrap(); @@ -780,8 +781,8 @@ fn send_and_spend_erc721_maker_payment() { fn send_and_spend_erc1155_maker_payment() { let erc1155_nft = TestNftType::Erc1155 { token_id: 4, amount: 3 }; - let maker_global_nft = global_nft_with_random_privkey(nft_swap_contract(), Some(erc1155_nft)); - let taker_global_nft = global_nft_with_random_privkey(nft_swap_contract(), None); + let maker_global_nft = global_nft_with_random_privkey(nft_maker_swap_v2(), Some(erc1155_nft)); + let taker_global_nft = global_nft_with_random_privkey(nft_maker_swap_v2(), None); let time_lock = now_sec() + 1000; let maker_pubkey = maker_global_nft.derive_htlc_pubkey(&[]); @@ -794,7 +795,7 @@ fn send_and_spend_erc1155_maker_payment() { token_address: &erc1155_contract(), token_id: &BigUint::from(4u32).to_bytes(), contract_type: &ContractType::Erc1155, - swap_contract_address: &nft_swap_contract(), + swap_contract_address: &nft_maker_swap_v2(), }; let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { @@ -840,7 +841,7 @@ fn send_and_spend_erc1155_maker_payment() { maker_pub: &maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), swap_unique_data: &[], contract_type: &ContractType::Erc1155, - swap_contract_address: &nft_swap_contract(), + swap_contract_address: &nft_maker_swap_v2(), }; let spend_tx = block_on(taker_global_nft.spend_nft_maker_payment_v2(spend_payment_args)).unwrap(); diff --git a/mm2src/mm2_main/tests/docker_tests_main.rs b/mm2src/mm2_main/tests/docker_tests_main.rs index e2147e3cea..233e5cf88d 100644 --- a/mm2src/mm2_main/tests/docker_tests_main.rs +++ b/mm2src/mm2_main/tests/docker_tests_main.rs @@ -24,6 +24,7 @@ extern crate serde_json; use std::io::{BufRead, BufReader}; use std::process::Command; +use std::time::Duration; use test::{test_main, StaticBenchFn, StaticTestFn, TestDescAndFn}; use testcontainers::clients::Cli; @@ -72,6 +73,7 @@ pub fn docker_tests_runner(tests: &[&TestDescAndFn]) { utxo_ops.wait_ready(4); utxo_ops1.wait_ready(4); + wait_for_geth_node_ready(); init_geth_node(); containers.push(utxo_node); @@ -100,6 +102,27 @@ pub fn docker_tests_runner(tests: &[&TestDescAndFn]) { test_main(&args, owned_tests, None); } +fn wait_for_geth_node_ready() { + let mut attempts = 0; + loop { + if attempts >= 5 { + println!("Failed to connect to Geth node after several attempts."); + break; + } + match block_on(GETH_WEB3.eth().block_number()) { + Ok(block_number) => { + println!("Geth node is ready, latest block number: {:?}", block_number); + break; + }, + Err(e) => { + println!("Failed to connect to Geth node: {:?}, retrying...", e); + attempts += 1; + thread::sleep(Duration::from_secs(5)); + }, + } + } +} + fn pull_docker_image(name: &str) { Command::new("docker") .arg("pull") From ff1006a7e33a84e2646fa0626f9381129c632466 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 22 Apr 2024 21:23:37 +0700 Subject: [PATCH 003/233] use Sepolia in dockerized nft tests --- .../tests/docker_tests/docker_tests_common.rs | 2 + .../tests/docker_tests/eth_docker_tests.rs | 91 ++++++++++++++----- mm2src/mm2_test_helpers/src/for_tests.rs | 17 ++++ 3 files changed, 89 insertions(+), 21 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index ffb396b1c0..821b8b233e 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -67,6 +67,7 @@ lazy_static! { static ref ETH_DISTRIBUTOR: EthCoin = eth_distributor(); pub static ref MM_CTX: MmArc = MmCtxBuilder::new().into_mm_arc(); pub static ref GETH_WEB3: Web3 = Web3::new(Http::new(GETH_RPC_URL).unwrap()); + pub static ref SEPOLIA_WEB3: Web3 = Web3::new(Http::new(SEPOLIA_RPC_URL).unwrap()); // Mutex used to prevent nonce re-usage during funding addresses used in tests pub static ref GETH_NONCE_LOCK: Mutex<()> = Mutex::new(()); } @@ -92,6 +93,7 @@ pub static mut GETH_NFT_SWAP_CONTRACT: H160Eth = H160Eth::zero(); /// NFT Maker Swap V2 contract address on Geth dev node pub static mut GETH_NFT_MAKER_SWAP_V2: H160Eth = H160Eth::zero(); pub static GETH_RPC_URL: &str = "http://127.0.0.1:8545"; +pub static SEPOLIA_RPC_URL: &str = "https://ethereum-sepolia-rpc.publicnode.com"; pub const UTXO_ASSET_DOCKER_IMAGE: &str = "docker.io/artempikulin/testblockchain"; pub const UTXO_ASSET_DOCKER_IMAGE_WITH_TAG: &str = "docker.io/artempikulin/testblockchain:multiarch"; diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 4151c334d8..a5fdd82539 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1,7 +1,8 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC721_TEST_ABI, GETH_ACCOUNT, GETH_ERC1155_CONTRACT, GETH_ERC20_CONTRACT, GETH_ERC721_CONTRACT, GETH_NFT_MAKER_SWAP_V2, GETH_NFT_SWAP_CONTRACT, GETH_NONCE_LOCK, GETH_RPC_URL, - GETH_SWAP_CONTRACT, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, MM_CTX}; + GETH_SWAP_CONTRACT, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, MM_CTX, SEPOLIA_RPC_URL, + SEPOLIA_WEB3}; use bitcrypto::{dhash160, sha256}; use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_request, EthCoin, ERC20_ABI}; use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; @@ -14,7 +15,8 @@ use crypto::Secp256k1Secret; use ethereum_types::U256; use futures01::Future; use mm2_number::{BigDecimal, BigUint}; -use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, nft_dev_conf}; +use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, nft_dev_conf, nft_sepolia_conf}; +use std::str::FromStr; use std::thread; use std::time::Duration; use web3::contract::{Contract, Options}; @@ -37,6 +39,7 @@ pub fn swap_contract() -> Address { unsafe { GETH_SWAP_CONTRACT } } /// GETH_NFT_SWAP_CONTRACT is set once during initialization before tests start pub fn nft_swap_contract() -> Address { unsafe { GETH_NFT_SWAP_CONTRACT } } +#[allow(dead_code)] /// # Safety /// /// GETH_NFT_MAKER_SWAP_V2 is set once during initialization before tests start @@ -55,11 +58,13 @@ pub fn erc20_contract() -> Address { unsafe { GETH_ERC20_CONTRACT } } /// Return ERC20 dev token contract address in checksum format pub fn erc20_contract_checksum() -> String { checksum_address(&format!("{:02x}", erc20_contract())) } +#[allow(dead_code)] /// # Safety /// /// GETH_ERC721_CONTRACT is set once during initialization before tests start pub fn erc721_contract() -> Address { unsafe { GETH_ERC721_CONTRACT } } +#[allow(dead_code)] /// # Safety /// /// GETH_ERC1155_CONTRACT is set once during initialization before tests start @@ -113,6 +118,7 @@ fn fill_erc20(to_addr: Address, amount: U256) { wait_for_confirmation(tx_hash); } +#[allow(dead_code)] pub(crate) fn mint_erc721(to_addr: Address, token_id: U256) { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc721_contract = Contract::from_json(GETH_WEB3.eth(), erc721_contract(), ERC721_TEST_ABI.as_bytes()).unwrap(); @@ -143,10 +149,12 @@ pub(crate) fn mint_erc721(to_addr: Address, token_id: U256) { pub(crate) fn erc712_owner(token_id: U256) -> Address { let _guard = GETH_NONCE_LOCK.lock().unwrap(); - let erc721_contract = Contract::from_json(GETH_WEB3.eth(), erc721_contract(), ERC721_TEST_ABI.as_bytes()).unwrap(); + let token_address = Address::from_str("0xde3a479f463c17a6f0a4cbe67e506467e97e2c52").unwrap(); + let erc721_contract = Contract::from_json(SEPOLIA_WEB3.eth(), token_address, ERC721_TEST_ABI.as_bytes()).unwrap(); block_on(erc721_contract.query("ownerOf", Token::Uint(token_id), None, Options::default(), None)).unwrap() } +#[allow(dead_code)] pub(crate) fn mint_erc1155(to_addr: Address, token_id: U256, amount: U256) { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc1155_contract = @@ -185,8 +193,8 @@ pub(crate) fn mint_erc1155(to_addr: Address, token_id: U256, amount: U256) { pub(crate) fn erc1155_balance(wallet_addr: Address, token_id: U256) -> U256 { let _guard = GETH_NONCE_LOCK.lock().unwrap(); - let erc1155_contract = - Contract::from_json(GETH_WEB3.eth(), erc1155_contract(), ERC1155_TEST_ABI.as_bytes()).unwrap(); + let token_address = Address::from_str("0xfb53b8764be6033d89ceacafa36631b09d60a1d2").unwrap(); + let erc1155_contract = Contract::from_json(SEPOLIA_WEB3.eth(), token_address, ERC1155_TEST_ABI.as_bytes()).unwrap(); block_on(erc1155_contract.query( "balanceOf", (Token::Address(wallet_addr), Token::Uint(token_id)), @@ -197,6 +205,7 @@ pub(crate) fn erc1155_balance(wallet_addr: Address, token_id: U256) -> U256 { .unwrap() } +#[allow(dead_code)] pub(crate) async fn fill_erc1155_info(eth_coin: &EthCoin, tokens_id: u32, amount: u32) { let nft_infos_lock = eth_coin.nfts_infos.clone(); let mut nft_infos = nft_infos_lock.lock().await; @@ -213,6 +222,7 @@ pub(crate) async fn fill_erc1155_info(eth_coin: &EthCoin, tokens_id: u32, amount nft_infos.insert(erc1155_key, erc1155_nft_info); } +#[allow(dead_code)] pub(crate) async fn fill_erc721_info(eth_coin: &EthCoin, tokens_id: u32) { let nft_infos_lock = eth_coin.nfts_infos.clone(); let mut nft_infos = nft_infos_lock.lock().await; @@ -292,6 +302,7 @@ pub fn erc20_coin_with_random_privkey(swap_contract_address: Address) -> EthCoin erc20_coin } +#[allow(dead_code)] pub enum TestNftType { Erc1155 { token_id: u32, amount: u32 }, Erc721 { token_id: u32 }, @@ -300,6 +311,7 @@ pub enum TestNftType { /// Generates a global NFT coin instance with a random private key and an initial 100 ETH balance. /// Optionally mints a specified NFT (either ERC721 or ERC1155) to the global NFT address, /// with details recorded in the `nfts_infos` field based on the provided `nft_type`. +#[allow(dead_code)] pub fn global_nft_with_random_privkey(swap_contract_address: Address, nft_type: Option) -> EthCoin { let nft_conf = nft_dev_conf(); let req = json!({ @@ -339,6 +351,31 @@ pub fn global_nft_with_random_privkey(swap_contract_address: Address, nft_type: global_nft } +fn global_nft_from_privkey(swap_contract_address: Address, secret: &'static str) -> EthCoin { + let nft_conf = nft_sepolia_conf(); + let req = json!({ + "method": "enable", + "coin": "NFT_ETH", + "urls": [SEPOLIA_RPC_URL], + "swap_contract_address": swap_contract_address, + }); + + let priv_key = Secp256k1Secret::from(secret); + let global_nft = block_on(eth_coin_from_conf_and_request( + &MM_CTX, + "NFT_ETH", + &nft_conf, + &req, + CoinProtocol::NFT { + platform: "ETH".to_string(), + }, + PrivKeyBuildPolicy::IguanaPrivKey(priv_key), + )) + .unwrap(); + + global_nft +} + /// Fills the private key's public address with ETH and ERC20 tokens pub fn fill_eth_erc20_with_private_key(priv_key: Secp256k1Secret) { let eth_conf = eth_dev_conf(); @@ -698,10 +735,16 @@ fn send_and_spend_erc721_maker_payment() { // Decision will inform whether to maintain multiple "swap_contract_address" fields in `EthCoin` for distinct contract types // or a singular field for a Diamond Standard-compatible contract address. - let erc721_nft = TestNftType::Erc721 { token_id: 2 }; + // Maker owns tokenId = 1 - let maker_global_nft = global_nft_with_random_privkey(nft_maker_swap_v2(), Some(erc721_nft)); - let taker_global_nft = global_nft_with_random_privkey(nft_maker_swap_v2(), None); + let etomic_swap_maker_nft_contract = Address::from_str("0x9eb88cd58605d8fb9b14652d6152727f7e95fb4d").unwrap(); + let erc721_contract = Address::from_str("0xde3a479f463c17a6f0a4cbe67e506467e97e2c52").unwrap(); + + let maker_priv = "6e2f3a6223b928a05a3a3622b0c3f3573d03663b704a61a6eb73326de0487928"; + let taker_priv = "e0be82dca60ff7e4c6d6db339ac9e1ae249af081dba2110bddd281e711608f16"; + + let maker_global_nft = global_nft_from_privkey(etomic_swap_maker_nft_contract, maker_priv); + let taker_global_nft = global_nft_from_privkey(etomic_swap_maker_nft_contract, taker_priv); let time_lock = now_sec() + 1000; let maker_pubkey = maker_global_nft.derive_htlc_pubkey(&[]); @@ -711,10 +754,10 @@ fn send_and_spend_erc721_maker_payment() { let maker_secret_hash = sha256(maker_secret).to_vec(); let nft_swap_info = NftSwapInfo { - token_address: &erc721_contract(), - token_id: &BigUint::from(2u32).to_bytes(), + token_address: &erc721_contract, + token_id: &BigUint::from(1u32).to_bytes(), contract_type: &ContractType::Erc721, - swap_contract_address: &nft_maker_swap_v2(), + swap_contract_address: &etomic_swap_maker_nft_contract, }; let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { @@ -760,7 +803,7 @@ fn send_and_spend_erc721_maker_payment() { maker_pub: &maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), swap_unique_data: &[], contract_type: &ContractType::Erc721, - swap_contract_address: &nft_maker_swap_v2(), + swap_contract_address: &etomic_swap_maker_nft_contract, }; let spend_tx = block_on(taker_global_nft.spend_nft_maker_payment_v2(spend_payment_args)).unwrap(); @@ -773,16 +816,22 @@ fn send_and_spend_erc721_maker_payment() { }; taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - let new_owner = erc712_owner(U256::from(2)); + let new_owner = erc712_owner(U256::from(1)); assert_eq!(new_owner, taker_global_nft.my_address); } #[test] fn send_and_spend_erc1155_maker_payment() { - let erc1155_nft = TestNftType::Erc1155 { token_id: 4, amount: 3 }; + // Maker owns tokenId = 1, amount = 3 + + let etomic_swap_maker_nft_contract = Address::from_str("0x9eb88cd58605d8fb9b14652d6152727f7e95fb4d").unwrap(); + let erc1155_contract = Address::from_str("0xfb53b8764be6033d89ceacafa36631b09d60a1d2").unwrap(); + + let maker_priv = "6e2f3a6223b928a05a3a3622b0c3f3573d03663b704a61a6eb73326de0487928"; + let taker_priv = "e0be82dca60ff7e4c6d6db339ac9e1ae249af081dba2110bddd281e711608f16"; - let maker_global_nft = global_nft_with_random_privkey(nft_maker_swap_v2(), Some(erc1155_nft)); - let taker_global_nft = global_nft_with_random_privkey(nft_maker_swap_v2(), None); + let maker_global_nft = global_nft_from_privkey(etomic_swap_maker_nft_contract, maker_priv); + let taker_global_nft = global_nft_from_privkey(etomic_swap_maker_nft_contract, taker_priv); let time_lock = now_sec() + 1000; let maker_pubkey = maker_global_nft.derive_htlc_pubkey(&[]); @@ -792,10 +841,10 @@ fn send_and_spend_erc1155_maker_payment() { let maker_secret_hash = sha256(maker_secret).to_vec(); let nft_swap_info = NftSwapInfo { - token_address: &erc1155_contract(), - token_id: &BigUint::from(4u32).to_bytes(), + token_address: &erc1155_contract, + token_id: &BigUint::from(1u32).to_bytes(), contract_type: &ContractType::Erc1155, - swap_contract_address: &nft_maker_swap_v2(), + swap_contract_address: &etomic_swap_maker_nft_contract, }; let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { @@ -841,7 +890,7 @@ fn send_and_spend_erc1155_maker_payment() { maker_pub: &maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), swap_unique_data: &[], contract_type: &ContractType::Erc1155, - swap_contract_address: &nft_maker_swap_v2(), + swap_contract_address: &etomic_swap_maker_nft_contract, }; let spend_tx = block_on(taker_global_nft.spend_nft_maker_payment_v2(spend_payment_args)).unwrap(); @@ -854,7 +903,7 @@ fn send_and_spend_erc1155_maker_payment() { }; taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - let balance = erc1155_balance(taker_global_nft.my_address, U256::from(4)); + let balance = erc1155_balance(taker_global_nft.my_address, U256::from(1)); assert_eq!(balance, U256::from(3)); } diff --git a/mm2src/mm2_test_helpers/src/for_tests.rs b/mm2src/mm2_test_helpers/src/for_tests.rs index f10388fb52..1e4af29097 100644 --- a/mm2src/mm2_test_helpers/src/for_tests.rs +++ b/mm2src/mm2_test_helpers/src/for_tests.rs @@ -844,6 +844,23 @@ pub fn nft_dev_conf() -> Json { }) } +/// global NFT configuration used for Sepolia testnet +pub fn nft_sepolia_conf() -> Json { + json!({ + "coin": "NFT_ETH", + "name": "nftdev", + "chain_id": 11155111, + "mm2": 1, + "derivation_path": "m/44'/60'", + "protocol": { + "type": "NFT", + "protocol_data": { + "platform": "ETH" + } + } + }) +} + pub fn eth_sepolia_conf() -> Json { json!({ "coin": "ETH", From aebf7568e5bc55955fedbeecb2e90667ee9875de Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Apr 2024 17:52:04 +0700 Subject: [PATCH 004/233] global variables and send nft back to maker --- mm2src/coins/eth.rs | 6 +- .../tests/docker_tests/docker_tests_common.rs | 8 +- .../tests/docker_tests/eth_docker_tests.rs | 189 +++++++++++++----- 3 files changed, 150 insertions(+), 53 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index ce88c3a352..2f2666db28 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -45,8 +45,8 @@ use crypto::{CryptoCtx, CryptoCtxError, GlobalHDAccountArc, KeyPairPolicy, Stand use derive_more::Display; use enum_derives::EnumFromStringify; use ethabi::{Contract, Function, Token}; -pub use ethcore_transaction::SignedTransaction as SignedEthTx; -use ethcore_transaction::{Action, Transaction as UnSignedEthTx, UnverifiedTransaction}; +pub use ethcore_transaction::{Action, SignedTransaction as SignedEthTx}; +use ethcore_transaction::{Transaction as UnSignedEthTx, UnverifiedTransaction}; use ethereum_types::{Address, H160, H256, U256}; use ethkey::{public_to_address, sign, verify_address, KeyPair, Public, Signature}; use futures::compat::Future01CompatExt; @@ -3445,7 +3445,7 @@ impl EthCoin { #[cfg_attr(test, mockable)] impl EthCoin { - pub(crate) fn sign_and_send_transaction(&self, value: U256, action: Action, data: Vec, gas: U256) -> EthTxFut { + pub fn sign_and_send_transaction(&self, value: U256, action: Action, data: Vec, gas: U256) -> EthTxFut { let ctx = try_tx_fus!(MmArc::from_weak(&self.ctx).ok_or("!ctx")); let coin = self.clone(); let fut = async move { diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 821b8b233e..0b1ea0297d 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -44,6 +44,7 @@ use serde_json::{self as json, Value as Json}; pub use std::env; use std::path::PathBuf; use std::process::Command; +use std::str::FromStr; use std::sync::Mutex; pub use std::thread; use std::time::Duration; @@ -51,6 +52,7 @@ use testcontainers::clients::Cli; use testcontainers::core::WaitFor; use testcontainers::{Container, GenericImage, RunnableImage}; use web3::transports::Http; +use web3::types::Address as EthAddress; use web3::types::{BlockId, BlockNumber, TransactionRequest}; use web3::Web3; @@ -70,6 +72,10 @@ lazy_static! { pub static ref SEPOLIA_WEB3: Web3 = Web3::new(Http::new(SEPOLIA_RPC_URL).unwrap()); // Mutex used to prevent nonce re-usage during funding addresses used in tests pub static ref GETH_NONCE_LOCK: Mutex<()> = Mutex::new(()); + pub static ref SEPOLIA_NONCE_LOCK: Mutex<()> = Mutex::new(()); + pub static ref SEPOLIA_ETOMIC_MAKER_NFT_SWAP: EthAddress = EthAddress::from_str("0x9eb88cd58605d8fb9b14652d6152727f7e95fb4d").unwrap(); + pub static ref SEPOLIA_ERC721_CONTRACT: EthAddress = EthAddress::from_str("0xde3a479f463c17a6f0a4cbe67e506467e97e2c52").unwrap(); + pub static ref SEPOLIA_ERC1155_CONTRACT: EthAddress = EthAddress::from_str("0xfb53b8764be6033d89ceacafa36631b09d60a1d2").unwrap(); } pub static mut QICK_TOKEN_ADDRESS: Option = None; @@ -93,7 +99,7 @@ pub static mut GETH_NFT_SWAP_CONTRACT: H160Eth = H160Eth::zero(); /// NFT Maker Swap V2 contract address on Geth dev node pub static mut GETH_NFT_MAKER_SWAP_V2: H160Eth = H160Eth::zero(); pub static GETH_RPC_URL: &str = "http://127.0.0.1:8545"; -pub static SEPOLIA_RPC_URL: &str = "https://ethereum-sepolia-rpc.publicnode.com"; +pub static SEPOLIA_RPC_URL: &str = "http://ethereum-sepolia-rpc.publicnode.com"; pub const UTXO_ASSET_DOCKER_IMAGE: &str = "docker.io/artempikulin/testblockchain"; pub const UTXO_ASSET_DOCKER_IMAGE_WITH_TAG: &str = "docker.io/artempikulin/testblockchain:multiarch"; diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index a5fdd82539..f747dd94e6 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1,10 +1,12 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC721_TEST_ABI, GETH_ACCOUNT, GETH_ERC1155_CONTRACT, GETH_ERC20_CONTRACT, GETH_ERC721_CONTRACT, GETH_NFT_MAKER_SWAP_V2, GETH_NFT_SWAP_CONTRACT, GETH_NONCE_LOCK, GETH_RPC_URL, - GETH_SWAP_CONTRACT, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, MM_CTX, SEPOLIA_RPC_URL, - SEPOLIA_WEB3}; + GETH_SWAP_CONTRACT, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, MM_CTX, + SEPOLIA_ERC1155_CONTRACT, SEPOLIA_ERC721_CONTRACT, SEPOLIA_ETOMIC_MAKER_NFT_SWAP, + SEPOLIA_NONCE_LOCK, SEPOLIA_RPC_URL, SEPOLIA_WEB3}; +use crate::common::Future01CompatExt; use bitcrypto::{dhash160, sha256}; -use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_request, EthCoin, ERC20_ABI}; +use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_request, Action, EthCoin, ERC20_ABI}; use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; use coins::{CoinProtocol, ConfirmPaymentInput, FoundSwapTxSpend, MakerNftSwapOpsV2, MarketCoinOps, NftSwapInfo, ParseCoinAssocTypes, PrivKeyBuildPolicy, RefundPaymentArgs, SearchForSwapTxSpendInput, @@ -16,13 +18,15 @@ use ethereum_types::U256; use futures01::Future; use mm2_number::{BigDecimal, BigUint}; use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, nft_dev_conf, nft_sepolia_conf}; -use std::str::FromStr; use std::thread; use std::time::Duration; use web3::contract::{Contract, Options}; use web3::ethabi::Token; use web3::types::{Address, TransactionRequest, H256}; +const SEPOLIA_MAKER_PRIV: &str = "6e2f3a6223b928a05a3a3622b0c3f3573d03663b704a61a6eb73326de0487928"; +const SEPOLIA_TAKER_PRIV: &str = "e0be82dca60ff7e4c6d6db339ac9e1ae249af081dba2110bddd281e711608f16"; + /// # Safety /// /// GETH_ACCOUNT is set once during initialization before tests start @@ -148,9 +152,9 @@ pub(crate) fn mint_erc721(to_addr: Address, token_id: U256) { } pub(crate) fn erc712_owner(token_id: U256) -> Address { - let _guard = GETH_NONCE_LOCK.lock().unwrap(); - let token_address = Address::from_str("0xde3a479f463c17a6f0a4cbe67e506467e97e2c52").unwrap(); - let erc721_contract = Contract::from_json(SEPOLIA_WEB3.eth(), token_address, ERC721_TEST_ABI.as_bytes()).unwrap(); + let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); + let erc721_contract = + Contract::from_json(SEPOLIA_WEB3.eth(), *SEPOLIA_ERC721_CONTRACT, ERC721_TEST_ABI.as_bytes()).unwrap(); block_on(erc721_contract.query("ownerOf", Token::Uint(token_id), None, Options::default(), None)).unwrap() } @@ -192,9 +196,13 @@ pub(crate) fn mint_erc1155(to_addr: Address, token_id: U256, amount: U256) { } pub(crate) fn erc1155_balance(wallet_addr: Address, token_id: U256) -> U256 { - let _guard = GETH_NONCE_LOCK.lock().unwrap(); - let token_address = Address::from_str("0xfb53b8764be6033d89ceacafa36631b09d60a1d2").unwrap(); - let erc1155_contract = Contract::from_json(SEPOLIA_WEB3.eth(), token_address, ERC1155_TEST_ABI.as_bytes()).unwrap(); + let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); + let erc1155_contract = Contract::from_json( + SEPOLIA_WEB3.eth(), + *SEPOLIA_ERC1155_CONTRACT, + ERC1155_TEST_ABI.as_bytes(), + ) + .unwrap(); block_on(erc1155_contract.query( "balanceOf", (Token::Address(wallet_addr), Token::Uint(token_id)), @@ -206,36 +214,36 @@ pub(crate) fn erc1155_balance(wallet_addr: Address, token_id: U256) -> U256 { } #[allow(dead_code)] -pub(crate) async fn fill_erc1155_info(eth_coin: &EthCoin, tokens_id: u32, amount: u32) { +pub(crate) async fn fill_erc1155_info(eth_coin: &EthCoin, token_address: Address, token_id: u32, amount: u32) { let nft_infos_lock = eth_coin.nfts_infos.clone(); let mut nft_infos = nft_infos_lock.lock().await; let erc1155_nft_info = NftInfo { - token_address: erc1155_contract(), - token_id: BigUint::from(tokens_id), + token_address, + token_id: BigUint::from(token_id), chain: Chain::Eth, contract_type: ContractType::Erc1155, amount: BigDecimal::from(amount), }; - let erc1155_address_str = eth_addr_to_hex(&erc1155_contract()); - let erc1155_key = format!("{},{}", erc1155_address_str, tokens_id); + let erc1155_address_str = eth_addr_to_hex(&token_address); + let erc1155_key = format!("{},{}", erc1155_address_str, token_id); nft_infos.insert(erc1155_key, erc1155_nft_info); } #[allow(dead_code)] -pub(crate) async fn fill_erc721_info(eth_coin: &EthCoin, tokens_id: u32) { +pub(crate) async fn fill_erc721_info(eth_coin: &EthCoin, token_address: Address, token_id: u32) { let nft_infos_lock = eth_coin.nfts_infos.clone(); let mut nft_infos = nft_infos_lock.lock().await; let erc721_nft_info = NftInfo { - token_address: erc721_contract(), - token_id: BigUint::from(tokens_id), + token_address, + token_id: BigUint::from(token_id), chain: Chain::Eth, contract_type: ContractType::Erc721, amount: BigDecimal::from(1), }; - let erc721_address_str = eth_addr_to_hex(&erc721_contract()); - let erc721_key = format!("{},{}", erc721_address_str, tokens_id); + let erc721_address_str = eth_addr_to_hex(&token_address); + let erc721_key = format!("{},{}", erc721_address_str, token_id); nft_infos.insert(erc721_key, erc721_nft_info); } @@ -302,7 +310,7 @@ pub fn erc20_coin_with_random_privkey(swap_contract_address: Address) -> EthCoin erc20_coin } -#[allow(dead_code)] +#[derive(Copy, Clone, Debug)] pub enum TestNftType { Erc1155 { token_id: u32, amount: u32 }, Erc721 { token_id: u32 }, @@ -339,11 +347,11 @@ pub fn global_nft_with_random_privkey(swap_contract_address: Address, nft_type: match nft_type { TestNftType::Erc1155 { token_id, amount } => { mint_erc1155(global_nft.my_address, U256::from(token_id), U256::from(amount)); - block_on(fill_erc1155_info(&global_nft, token_id, amount)); + block_on(fill_erc1155_info(&global_nft, erc1155_contract(), token_id, amount)); }, TestNftType::Erc721 { token_id } => { mint_erc721(global_nft.my_address, U256::from(token_id)); - block_on(fill_erc721_info(&global_nft, token_id)); + block_on(fill_erc721_info(&global_nft, erc721_contract(), token_id)); }, } } @@ -351,7 +359,11 @@ pub fn global_nft_with_random_privkey(swap_contract_address: Address, nft_type: global_nft } -fn global_nft_from_privkey(swap_contract_address: Address, secret: &'static str) -> EthCoin { +fn global_nft_from_privkey( + swap_contract_address: Address, + secret: &'static str, + nft_type: Option, +) -> EthCoin { let nft_conf = nft_sepolia_conf(); let req = json!({ "method": "enable", @@ -373,9 +385,73 @@ fn global_nft_from_privkey(swap_contract_address: Address, secret: &'static str) )) .unwrap(); + if let Some(nft_type) = nft_type { + match nft_type { + TestNftType::Erc1155 { token_id, amount } => { + block_on(fill_erc1155_info( + &global_nft, + *SEPOLIA_ERC1155_CONTRACT, + token_id, + amount, + )); + }, + TestNftType::Erc721 { token_id } => { + block_on(fill_erc721_info(&global_nft, *SEPOLIA_ERC721_CONTRACT, token_id)); + }, + } + } + global_nft } +fn send_safe_transfer_from( + global_nft: &EthCoin, + token_address: Address, + to_address: Address, + nft_type: TestNftType, +) -> web3::Result<()> { + let _guard = GETH_NONCE_LOCK.lock().unwrap(); + + let contract = match nft_type { + TestNftType::Erc1155 { .. } => { + Contract::from_json(SEPOLIA_WEB3.eth(), token_address, ERC1155_TEST_ABI.as_bytes()).unwrap() + }, + TestNftType::Erc721 { .. } => { + Contract::from_json(SEPOLIA_WEB3.eth(), token_address, ERC721_TEST_ABI.as_bytes()).unwrap() + }, + }; + let tokens = match nft_type { + TestNftType::Erc1155 { token_id, amount } => vec![ + Token::Address(global_nft.my_address), + Token::Address(to_address), + Token::Uint(U256::from(token_id)), + Token::Uint(U256::from(amount)), + Token::Bytes(vec![]), + ], + TestNftType::Erc721 { token_id } => vec![ + Token::Address(global_nft.my_address), + Token::Address(to_address), + Token::Uint(U256::from(token_id)), + ], + }; + + let data = contract + .abi() + .function("safeTransferFrom") + .unwrap() + .encode_input(&tokens) + .unwrap(); + + let result = block_on( + global_nft + .sign_and_send_transaction(0.into(), Action::Call(token_address), data, U256::from(150_000)) + .compat(), + ); + + println!("Transaction sent: {:?}", result); + Ok(()) +} + /// Fills the private key's public address with ETH and ERC20 tokens pub fn fill_eth_erc20_with_private_key(priv_key: Secp256k1Secret) { let eth_conf = eth_dev_conf(); @@ -735,16 +811,13 @@ fn send_and_spend_erc721_maker_payment() { // Decision will inform whether to maintain multiple "swap_contract_address" fields in `EthCoin` for distinct contract types // or a singular field for a Diamond Standard-compatible contract address. - // Maker owns tokenId = 1 - - let etomic_swap_maker_nft_contract = Address::from_str("0x9eb88cd58605d8fb9b14652d6152727f7e95fb4d").unwrap(); - let erc721_contract = Address::from_str("0xde3a479f463c17a6f0a4cbe67e506467e97e2c52").unwrap(); + // Sepolia Maker owns tokenId = 1 - let maker_priv = "6e2f3a6223b928a05a3a3622b0c3f3573d03663b704a61a6eb73326de0487928"; - let taker_priv = "e0be82dca60ff7e4c6d6db339ac9e1ae249af081dba2110bddd281e711608f16"; + let erc721_nft = TestNftType::Erc721 { token_id: 1 }; - let maker_global_nft = global_nft_from_privkey(etomic_swap_maker_nft_contract, maker_priv); - let taker_global_nft = global_nft_from_privkey(etomic_swap_maker_nft_contract, taker_priv); + let maker_global_nft = + global_nft_from_privkey(*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, SEPOLIA_MAKER_PRIV, Some(erc721_nft)); + let taker_global_nft = global_nft_from_privkey(*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, SEPOLIA_TAKER_PRIV, None); let time_lock = now_sec() + 1000; let maker_pubkey = maker_global_nft.derive_htlc_pubkey(&[]); @@ -754,10 +827,10 @@ fn send_and_spend_erc721_maker_payment() { let maker_secret_hash = sha256(maker_secret).to_vec(); let nft_swap_info = NftSwapInfo { - token_address: &erc721_contract, + token_address: &*SEPOLIA_ERC721_CONTRACT, token_id: &BigUint::from(1u32).to_bytes(), contract_type: &ContractType::Erc721, - swap_contract_address: &etomic_swap_maker_nft_contract, + swap_contract_address: &*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, }; let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { @@ -803,7 +876,7 @@ fn send_and_spend_erc721_maker_payment() { maker_pub: &maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), swap_unique_data: &[], contract_type: &ContractType::Erc721, - swap_contract_address: &etomic_swap_maker_nft_contract, + swap_contract_address: &*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, }; let spend_tx = block_on(taker_global_nft.spend_nft_maker_payment_v2(spend_payment_args)).unwrap(); @@ -818,20 +891,28 @@ fn send_and_spend_erc721_maker_payment() { let new_owner = erc712_owner(U256::from(1)); assert_eq!(new_owner, taker_global_nft.my_address); + + // send nft back to maker + send_safe_transfer_from( + &taker_global_nft, + *SEPOLIA_ERC721_CONTRACT, + maker_global_nft.my_address, + erc721_nft, + ) + .unwrap(); + let new_owner = erc712_owner(U256::from(1)); + assert_eq!(new_owner, maker_global_nft.my_address); } #[test] fn send_and_spend_erc1155_maker_payment() { - // Maker owns tokenId = 1, amount = 3 + // Sepolia Maker owns tokenId = 1, amount = 3 - let etomic_swap_maker_nft_contract = Address::from_str("0x9eb88cd58605d8fb9b14652d6152727f7e95fb4d").unwrap(); - let erc1155_contract = Address::from_str("0xfb53b8764be6033d89ceacafa36631b09d60a1d2").unwrap(); + let erc1155_nft = TestNftType::Erc1155 { token_id: 1, amount: 3 }; - let maker_priv = "6e2f3a6223b928a05a3a3622b0c3f3573d03663b704a61a6eb73326de0487928"; - let taker_priv = "e0be82dca60ff7e4c6d6db339ac9e1ae249af081dba2110bddd281e711608f16"; - - let maker_global_nft = global_nft_from_privkey(etomic_swap_maker_nft_contract, maker_priv); - let taker_global_nft = global_nft_from_privkey(etomic_swap_maker_nft_contract, taker_priv); + let maker_global_nft = + global_nft_from_privkey(*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, SEPOLIA_MAKER_PRIV, Some(erc1155_nft)); + let taker_global_nft = global_nft_from_privkey(*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, SEPOLIA_TAKER_PRIV, None); let time_lock = now_sec() + 1000; let maker_pubkey = maker_global_nft.derive_htlc_pubkey(&[]); @@ -841,10 +922,10 @@ fn send_and_spend_erc1155_maker_payment() { let maker_secret_hash = sha256(maker_secret).to_vec(); let nft_swap_info = NftSwapInfo { - token_address: &erc1155_contract, + token_address: &*SEPOLIA_ERC1155_CONTRACT, token_id: &BigUint::from(1u32).to_bytes(), contract_type: &ContractType::Erc1155, - swap_contract_address: &etomic_swap_maker_nft_contract, + swap_contract_address: &*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, }; let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { @@ -863,7 +944,7 @@ fn send_and_spend_erc1155_maker_payment() { payment_tx: maker_payment.tx_hex(), confirmations: 1, requires_nota: false, - wait_until: now_sec() + 60, + wait_until: now_sec() + 80, check_every: 1, }; maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); @@ -890,7 +971,7 @@ fn send_and_spend_erc1155_maker_payment() { maker_pub: &maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), swap_unique_data: &[], contract_type: &ContractType::Erc1155, - swap_contract_address: &etomic_swap_maker_nft_contract, + swap_contract_address: &*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, }; let spend_tx = block_on(taker_global_nft.spend_nft_maker_payment_v2(spend_payment_args)).unwrap(); @@ -898,13 +979,24 @@ fn send_and_spend_erc1155_maker_payment() { payment_tx: spend_tx.tx_hex(), confirmations: 1, requires_nota: false, - wait_until: now_sec() + 60, + wait_until: now_sec() + 80, check_every: 1, }; taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); let balance = erc1155_balance(taker_global_nft.my_address, U256::from(1)); assert_eq!(balance, U256::from(3)); + + // send nft back to maker + send_safe_transfer_from( + &taker_global_nft, + *SEPOLIA_ERC1155_CONTRACT, + maker_global_nft.my_address, + erc1155_nft, + ) + .unwrap(); + let balance = erc1155_balance(maker_global_nft.my_address, U256::from(1)); + assert_eq!(balance, U256::from(3)); } #[test] @@ -922,7 +1014,6 @@ fn test_nonce_several_urls() { #[test] fn test_nonce_lock() { - use crate::common::Future01CompatExt; use futures::future::join_all; use mm2_test_helpers::for_tests::wait_for_log; From 1966fcf6b43076b815f80d7af6b3cce76242b1c4 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Apr 2024 19:21:39 +0700 Subject: [PATCH 005/233] add web3 HTTPS support in mm2_main tests --- Cargo.lock | 141 +++++++++++++++--- mm2src/mm2_main/Cargo.toml | 2 +- .../tests/docker_tests/docker_tests_common.rs | 2 +- 3 files changed, 124 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4604c8bc2c..9eedf8054a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -327,7 +327,7 @@ checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", - "bitflags", + "bitflags 1.3.2", "bytes 1.4.0", "futures-util", "http 0.2.12", @@ -544,6 +544,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + [[package]] name = "bitvec" version = "0.18.5" @@ -973,7 +979,7 @@ checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ "ansi_term", "atty", - "bitflags", + "bitflags 1.3.2", "strsim 0.8.0", "textwrap", "unicode-width", @@ -986,7 +992,7 @@ version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -995,7 +1001,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -2461,6 +2467,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.0.1" @@ -3152,6 +3173,19 @@ dependencies = [ "tokio-io-timeout", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes 1.4.0", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "iana-time-zone" version = "0.1.53" @@ -3521,7 +3555,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" dependencies = [ "arrayvec 0.5.1", - "bitflags", + "bitflags 1.3.2", "cfg-if 1.0.0", "ryu", "static_assertions", @@ -4887,6 +4921,24 @@ dependencies = [ "unsigned-varint", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "netlink-packet-core" version = "0.4.2" @@ -4906,7 +4958,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9ea4302b9759a7a88242299225ea3688e63c85ea136371bb6cf94fd674efaab" dependencies = [ "anyhow", - "bitflags", + "bitflags 1.3.2", "byteorder", "libc", "netlink-packet-core", @@ -4968,7 +5020,7 @@ version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cc", "cfg-if 1.0.0", "libc", @@ -4981,7 +5033,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if 1.0.0", "libc", ] @@ -5119,12 +5171,50 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.4.2", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.38", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "ordered-float" version = "3.7.0" @@ -5463,7 +5553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" dependencies = [ "autocfg 1.1.0", - "bitflags", + "bitflags 1.3.2", "cfg-if 1.0.0", "concurrent-queue 2.2.0", "libc", @@ -6034,7 +6124,7 @@ version = "10.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c49596760fce12ca21550ac21dc5a9617b2ea4b6e0aa7d8dab8ff2824fc2bba" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -6095,7 +6185,7 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -6172,11 +6262,13 @@ dependencies = [ "http-body 0.4.5", "hyper", "hyper-rustls 0.23.0", + "hyper-tls", "ipnet", "js-sys", "lazy_static", "log", "mime", + "native-tls", "percent-encoding", "pin-project-lite 0.2.9", "rustls 0.20.4", @@ -6185,6 +6277,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "tokio", + "tokio-native-tls", "tokio-rustls 0.23.2", "url", "wasm-bindgen", @@ -6368,7 +6461,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -6437,7 +6530,7 @@ version = "0.36.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno 0.2.8", "io-lifetimes", "libc", @@ -6451,7 +6544,7 @@ version = "0.37.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno 0.3.1", "io-lifetimes", "libc", @@ -6706,7 +6799,7 @@ version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -7440,7 +7533,7 @@ checksum = "0a463f546a2f5842d35974bd4691ae5ceded6785ec24db440f773723f6ce4e11" dependencies = [ "base64 0.13.0", "bincode", - "bitflags", + "bitflags 1.3.2", "blake3", "borsh", "borsh-derive", @@ -7594,7 +7687,7 @@ dependencies = [ "assert_matches", "base64 0.13.0", "bincode", - "bitflags", + "bitflags 1.3.2", "borsh", "bs58 0.4.0", "bytemuck", @@ -7742,7 +7835,7 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77963e2aa8fadb589118c3aede2e78b6c4bcf1c01d588fbf33e915b390825fbd" dependencies = [ - "bitflags", + "bitflags 1.3.2", "byteorder", "hash-db", "hash256-std-hasher", @@ -8086,7 +8179,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "system-configuration-sys", ] @@ -8434,6 +8527,16 @@ dependencies = [ "syn 2.0.38", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.23.2" diff --git a/mm2src/mm2_main/Cargo.toml b/mm2src/mm2_main/Cargo.toml index 5244f03da4..28accb36c3 100644 --- a/mm2src/mm2_main/Cargo.toml +++ b/mm2src/mm2_main/Cargo.toml @@ -124,7 +124,7 @@ winapi = "0.3" mm2_test_helpers = { path = "../mm2_test_helpers" } mocktopus = "0.8.0" testcontainers = "0.15.0" -web3 = { git = "https://github.com/KomodoPlatform/rust-web3", tag = "v0.19.0", default-features = false, features = ["http"] } +web3 = { git = "https://github.com/KomodoPlatform/rust-web3", tag = "v0.19.0", default-features = false, features = ["http-tls"] } ethabi = { version = "17.0.0" } [build-dependencies] diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 0b1ea0297d..b37e1db5c6 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -99,7 +99,7 @@ pub static mut GETH_NFT_SWAP_CONTRACT: H160Eth = H160Eth::zero(); /// NFT Maker Swap V2 contract address on Geth dev node pub static mut GETH_NFT_MAKER_SWAP_V2: H160Eth = H160Eth::zero(); pub static GETH_RPC_URL: &str = "http://127.0.0.1:8545"; -pub static SEPOLIA_RPC_URL: &str = "http://ethereum-sepolia-rpc.publicnode.com"; +pub static SEPOLIA_RPC_URL: &str = "https://ethereum-sepolia-rpc.publicnode.com"; pub const UTXO_ASSET_DOCKER_IMAGE: &str = "docker.io/artempikulin/testblockchain"; pub const UTXO_ASSET_DOCKER_IMAGE_WITH_TAG: &str = "docker.io/artempikulin/testblockchain:multiarch"; From 1922bffff20ed8f8253b07cc25a44e916fa18aa3 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Apr 2024 20:35:08 +0700 Subject: [PATCH 006/233] wait for send_back_tx confirmation --- .../tests/docker_tests/eth_docker_tests.rs | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index f747dd94e6..8da5ebfd61 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -6,7 +6,8 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC7 SEPOLIA_NONCE_LOCK, SEPOLIA_RPC_URL, SEPOLIA_WEB3}; use crate::common::Future01CompatExt; use bitcrypto::{dhash160, sha256}; -use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_request, Action, EthCoin, ERC20_ABI}; +use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_request, Action, EthCoin, SignedEthTx, + ERC20_ABI}; use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; use coins::{CoinProtocol, ConfirmPaymentInput, FoundSwapTxSpend, MakerNftSwapOpsV2, MarketCoinOps, NftSwapInfo, ParseCoinAssocTypes, PrivKeyBuildPolicy, RefundPaymentArgs, SearchForSwapTxSpendInput, @@ -409,7 +410,7 @@ fn send_safe_transfer_from( token_address: Address, to_address: Address, nft_type: TestNftType, -) -> web3::Result<()> { +) -> web3::Result { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let contract = match nft_type { @@ -446,10 +447,11 @@ fn send_safe_transfer_from( global_nft .sign_and_send_transaction(0.into(), Action::Call(token_address), data, U256::from(150_000)) .compat(), - ); + ) + .unwrap(); println!("Transaction sent: {:?}", result); - Ok(()) + Ok(result) } /// Fills the private key's public address with ETH and ERC20 tokens @@ -893,13 +895,22 @@ fn send_and_spend_erc721_maker_payment() { assert_eq!(new_owner, taker_global_nft.my_address); // send nft back to maker - send_safe_transfer_from( + let send_back_tx = send_safe_transfer_from( &taker_global_nft, *SEPOLIA_ERC721_CONTRACT, maker_global_nft.my_address, erc721_nft, ) .unwrap(); + let confirm_input = ConfirmPaymentInput { + payment_tx: send_back_tx.tx_hex(), + confirmations: 1, + requires_nota: false, + wait_until: now_sec() + 70, + check_every: 1, + }; + taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + let new_owner = erc712_owner(U256::from(1)); assert_eq!(new_owner, maker_global_nft.my_address); } @@ -988,13 +999,21 @@ fn send_and_spend_erc1155_maker_payment() { assert_eq!(balance, U256::from(3)); // send nft back to maker - send_safe_transfer_from( + let send_back_tx = send_safe_transfer_from( &taker_global_nft, *SEPOLIA_ERC1155_CONTRACT, maker_global_nft.my_address, erc1155_nft, ) .unwrap(); + let confirm_input = ConfirmPaymentInput { + payment_tx: send_back_tx.tx_hex(), + confirmations: 1, + requires_nota: false, + wait_until: now_sec() + 80, + check_every: 1, + }; + taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); let balance = erc1155_balance(maker_global_nft.my_address, U256::from(1)); assert_eq!(balance, U256::from(3)); } From c07e8e2f62ec8447bb90c19a49586f831dd8b266 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Apr 2024 21:10:53 +0700 Subject: [PATCH 007/233] call contract addresses with functions --- .../tests/docker_tests/docker_tests_common.rs | 10 +++- .../tests/docker_tests/eth_docker_tests.rs | 60 ++++++++++--------- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index b37e1db5c6..2bf6c24411 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -73,9 +73,6 @@ lazy_static! { // Mutex used to prevent nonce re-usage during funding addresses used in tests pub static ref GETH_NONCE_LOCK: Mutex<()> = Mutex::new(()); pub static ref SEPOLIA_NONCE_LOCK: Mutex<()> = Mutex::new(()); - pub static ref SEPOLIA_ETOMIC_MAKER_NFT_SWAP: EthAddress = EthAddress::from_str("0x9eb88cd58605d8fb9b14652d6152727f7e95fb4d").unwrap(); - pub static ref SEPOLIA_ERC721_CONTRACT: EthAddress = EthAddress::from_str("0xde3a479f463c17a6f0a4cbe67e506467e97e2c52").unwrap(); - pub static ref SEPOLIA_ERC1155_CONTRACT: EthAddress = EthAddress::from_str("0xfb53b8764be6033d89ceacafa36631b09d60a1d2").unwrap(); } pub static mut QICK_TOKEN_ADDRESS: Option = None; @@ -98,6 +95,9 @@ pub static mut GETH_ERC1155_CONTRACT: H160Eth = H160Eth::zero(); pub static mut GETH_NFT_SWAP_CONTRACT: H160Eth = H160Eth::zero(); /// NFT Maker Swap V2 contract address on Geth dev node pub static mut GETH_NFT_MAKER_SWAP_V2: H160Eth = H160Eth::zero(); +pub static mut SEPOLIA_ETOMIC_MAKER_NFT_SWAP: H160Eth = H160Eth::zero(); +pub static mut SEPOLIA_ERC721_CONTRACT: H160Eth = H160Eth::zero(); +pub static mut SEPOLIA_ERC1155_CONTRACT: H160Eth = H160Eth::zero(); pub static GETH_RPC_URL: &str = "http://127.0.0.1:8545"; pub static SEPOLIA_RPC_URL: &str = "https://ethereum-sepolia-rpc.publicnode.com"; @@ -1412,6 +1412,10 @@ pub fn init_geth_node() { thread::sleep(Duration::from_millis(100)); } + SEPOLIA_ETOMIC_MAKER_NFT_SWAP = EthAddress::from_str("0x9eb88cd58605d8fb9b14652d6152727f7e95fb4d").unwrap(); + SEPOLIA_ERC721_CONTRACT = EthAddress::from_str("0xde3a479f463c17a6f0a4cbe67e506467e97e2c52").unwrap(); + SEPOLIA_ERC1155_CONTRACT = EthAddress::from_str("0xfb53b8764be6033d89ceacafa36631b09d60a1d2").unwrap(); + let alice_passphrase = get_passphrase!(".env.client", "ALICE_PASSPHRASE").unwrap(); let alice_keypair = key_pair_from_seed(&alice_passphrase).unwrap(); let alice_eth_addr = addr_from_raw_pubkey(alice_keypair.public()).unwrap(); diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 8da5ebfd61..a73bef9676 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -75,6 +75,21 @@ pub fn erc721_contract() -> Address { unsafe { GETH_ERC721_CONTRACT } } /// GETH_ERC1155_CONTRACT is set once during initialization before tests start pub fn erc1155_contract() -> Address { unsafe { GETH_ERC1155_CONTRACT } } +/// # Safety +/// +/// SEPOLIA_ETOMIC_MAKER_NFT_SWAP address is set once during initialization before tests start +pub fn sepolia_etomic_maker_nft() -> Address { unsafe { SEPOLIA_ETOMIC_MAKER_NFT_SWAP } } + +/// # Safety +/// +/// SEPOLIA_ERC721_CONTRACT address is set once during initialization before tests start +pub fn sepolia_erc721() -> Address { unsafe { SEPOLIA_ERC721_CONTRACT } } + +/// # Safety +/// +/// SEPOLIA_ERC1155_CONTRACT address is set once during initialization before tests start +pub fn sepolia_erc1155() -> Address { unsafe { SEPOLIA_ERC1155_CONTRACT } } + fn wait_for_confirmation(tx_hash: H256) { loop { match block_on(GETH_WEB3.eth().transaction_receipt(tx_hash)) { @@ -155,7 +170,7 @@ pub(crate) fn mint_erc721(to_addr: Address, token_id: U256) { pub(crate) fn erc712_owner(token_id: U256) -> Address { let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); let erc721_contract = - Contract::from_json(SEPOLIA_WEB3.eth(), *SEPOLIA_ERC721_CONTRACT, ERC721_TEST_ABI.as_bytes()).unwrap(); + Contract::from_json(SEPOLIA_WEB3.eth(), sepolia_erc721(), ERC721_TEST_ABI.as_bytes()).unwrap(); block_on(erc721_contract.query("ownerOf", Token::Uint(token_id), None, Options::default(), None)).unwrap() } @@ -198,12 +213,8 @@ pub(crate) fn mint_erc1155(to_addr: Address, token_id: U256, amount: U256) { pub(crate) fn erc1155_balance(wallet_addr: Address, token_id: U256) -> U256 { let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); - let erc1155_contract = Contract::from_json( - SEPOLIA_WEB3.eth(), - *SEPOLIA_ERC1155_CONTRACT, - ERC1155_TEST_ABI.as_bytes(), - ) - .unwrap(); + let erc1155_contract = + Contract::from_json(SEPOLIA_WEB3.eth(), sepolia_erc1155(), ERC1155_TEST_ABI.as_bytes()).unwrap(); block_on(erc1155_contract.query( "balanceOf", (Token::Address(wallet_addr), Token::Uint(token_id)), @@ -389,15 +400,10 @@ fn global_nft_from_privkey( if let Some(nft_type) = nft_type { match nft_type { TestNftType::Erc1155 { token_id, amount } => { - block_on(fill_erc1155_info( - &global_nft, - *SEPOLIA_ERC1155_CONTRACT, - token_id, - amount, - )); + block_on(fill_erc1155_info(&global_nft, sepolia_erc1155(), token_id, amount)); }, TestNftType::Erc721 { token_id } => { - block_on(fill_erc721_info(&global_nft, *SEPOLIA_ERC721_CONTRACT, token_id)); + block_on(fill_erc721_info(&global_nft, sepolia_erc721(), token_id)); }, } } @@ -817,9 +823,8 @@ fn send_and_spend_erc721_maker_payment() { let erc721_nft = TestNftType::Erc721 { token_id: 1 }; - let maker_global_nft = - global_nft_from_privkey(*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, SEPOLIA_MAKER_PRIV, Some(erc721_nft)); - let taker_global_nft = global_nft_from_privkey(*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, SEPOLIA_TAKER_PRIV, None); + let maker_global_nft = global_nft_from_privkey(sepolia_etomic_maker_nft(), SEPOLIA_MAKER_PRIV, Some(erc721_nft)); + let taker_global_nft = global_nft_from_privkey(sepolia_etomic_maker_nft(), SEPOLIA_TAKER_PRIV, None); let time_lock = now_sec() + 1000; let maker_pubkey = maker_global_nft.derive_htlc_pubkey(&[]); @@ -829,10 +834,10 @@ fn send_and_spend_erc721_maker_payment() { let maker_secret_hash = sha256(maker_secret).to_vec(); let nft_swap_info = NftSwapInfo { - token_address: &*SEPOLIA_ERC721_CONTRACT, + token_address: &sepolia_erc721(), token_id: &BigUint::from(1u32).to_bytes(), contract_type: &ContractType::Erc721, - swap_contract_address: &*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, + swap_contract_address: &sepolia_etomic_maker_nft(), }; let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { @@ -878,7 +883,7 @@ fn send_and_spend_erc721_maker_payment() { maker_pub: &maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), swap_unique_data: &[], contract_type: &ContractType::Erc721, - swap_contract_address: &*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, + swap_contract_address: &sepolia_etomic_maker_nft(), }; let spend_tx = block_on(taker_global_nft.spend_nft_maker_payment_v2(spend_payment_args)).unwrap(); @@ -897,7 +902,7 @@ fn send_and_spend_erc721_maker_payment() { // send nft back to maker let send_back_tx = send_safe_transfer_from( &taker_global_nft, - *SEPOLIA_ERC721_CONTRACT, + sepolia_erc721(), maker_global_nft.my_address, erc721_nft, ) @@ -921,9 +926,8 @@ fn send_and_spend_erc1155_maker_payment() { let erc1155_nft = TestNftType::Erc1155 { token_id: 1, amount: 3 }; - let maker_global_nft = - global_nft_from_privkey(*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, SEPOLIA_MAKER_PRIV, Some(erc1155_nft)); - let taker_global_nft = global_nft_from_privkey(*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, SEPOLIA_TAKER_PRIV, None); + let maker_global_nft = global_nft_from_privkey(sepolia_etomic_maker_nft(), SEPOLIA_MAKER_PRIV, Some(erc1155_nft)); + let taker_global_nft = global_nft_from_privkey(sepolia_etomic_maker_nft(), SEPOLIA_TAKER_PRIV, None); let time_lock = now_sec() + 1000; let maker_pubkey = maker_global_nft.derive_htlc_pubkey(&[]); @@ -933,10 +937,10 @@ fn send_and_spend_erc1155_maker_payment() { let maker_secret_hash = sha256(maker_secret).to_vec(); let nft_swap_info = NftSwapInfo { - token_address: &*SEPOLIA_ERC1155_CONTRACT, + token_address: &sepolia_erc1155(), token_id: &BigUint::from(1u32).to_bytes(), contract_type: &ContractType::Erc1155, - swap_contract_address: &*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, + swap_contract_address: &sepolia_etomic_maker_nft(), }; let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { @@ -982,7 +986,7 @@ fn send_and_spend_erc1155_maker_payment() { maker_pub: &maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), swap_unique_data: &[], contract_type: &ContractType::Erc1155, - swap_contract_address: &*SEPOLIA_ETOMIC_MAKER_NFT_SWAP, + swap_contract_address: &sepolia_etomic_maker_nft(), }; let spend_tx = block_on(taker_global_nft.spend_nft_maker_payment_v2(spend_payment_args)).unwrap(); @@ -1001,7 +1005,7 @@ fn send_and_spend_erc1155_maker_payment() { // send nft back to maker let send_back_tx = send_safe_transfer_from( &taker_global_nft, - *SEPOLIA_ERC1155_CONTRACT, + sepolia_erc1155(), maker_global_nft.my_address, erc1155_nft, ) From ebac6e6b86bba28738499a986280153fdcb62616 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 4 Apr 2024 21:35:48 +0700 Subject: [PATCH 008/233] impl check_token_uri and make chains field in ClearNftDbReq optional for user --- mm2src/coins/nft.rs | 60 ++++++++++++++++++++++++++++----- mm2src/coins/nft/nft_errors.rs | 1 + mm2src/coins/nft/nft_structs.rs | 1 + mm2src/coins/nft/nft_tests.rs | 10 +++++- 4 files changed, 63 insertions(+), 9 deletions(-) diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index 8e73e2b272..ee21e8e854 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -23,6 +23,7 @@ use crate::nft::nft_structs::{build_nft_with_empty_meta, BuildNftFields, ClearNf NftTransferCommon, PhishingDomainReq, PhishingDomainRes, RefreshMetadataReq, SpamContractReq, SpamContractRes, TransferMeta, TransferStatus, UriMeta}; use crate::nft::storage::{NftListStorageOps, NftTransferHistoryStorageOps}; +use common::log::error; use common::parse_rfc3339_to_timestamp; use crypto::StandardHDCoinAddress; use ethereum_types::{Address, H256}; @@ -458,7 +459,7 @@ pub async fn refresh_nft_metadata(ctx: MmArc, req: RefreshMetadataReq) -> MmResu let storage = nft_ctx.lock_db().await?; let token_address_str = eth_addr_to_hex(&req.token_address); - let moralis_meta = match get_moralis_metadata( + let mut moralis_meta = match get_moralis_metadata( token_address_str.clone(), req.token_id.clone(), &req.chain, @@ -487,10 +488,14 @@ pub async fn refresh_nft_metadata(ctx: MmArc, req: RefreshMetadataReq) -> MmResu })?; let token_uri = check_moralis_ipfs_bafy(moralis_meta.common.token_uri.as_deref()); let token_domain = get_domain_from_url(token_uri.as_deref()); + check_token_uri(&mut moralis_meta.common.possible_spam, token_uri.as_deref())?; + drop_mutability!(moralis_meta); let uri_meta = get_uri_meta( token_uri.as_deref(), moralis_meta.common.metadata.as_deref(), &req.url_antispam, + moralis_meta.common.possible_spam, + nft_db.possible_phishing, ) .await; // Gather domains for phishing checks @@ -911,14 +916,23 @@ fn check_moralis_ipfs_bafy(token_uri: Option<&str>) -> Option { }) } -async fn get_uri_meta(token_uri: Option<&str>, metadata: Option<&str>, url_antispam: &Url) -> UriMeta { +async fn get_uri_meta( + token_uri: Option<&str>, + metadata: Option<&str>, + url_antispam: &Url, + possible_spam: bool, + possible_phishing: bool, +) -> UriMeta { let mut uri_meta = UriMeta::default(); - // Fetching data from the URL if token_uri is provided - if let Some(token_uri) = token_uri { - if let Some(url) = construct_camo_url_with_token(token_uri, url_antispam) { - uri_meta = fetch_meta_from_url(url).await.unwrap_or_default(); + if !possible_spam && !possible_phishing { + // Fetching data from the URL if token_uri is provided + if let Some(token_uri) = token_uri { + if let Some(url) = construct_camo_url_with_token(token_uri, url_antispam) { + uri_meta = fetch_meta_from_url(url).await.unwrap_or_default(); + } } } + // Filling fields from metadata if provided if let Some(metadata) = metadata { if let Ok(meta_from_meta) = serde_json::from_str::(metadata) { @@ -1175,8 +1189,18 @@ async fn handle_receive_erc1155) -> MmResult<(), regex::Error> { + if let Some(uri) = token_uri { + if is_malicious(uri)? { + *possible_spam = true; + } + } + Ok(()) +} + async fn create_nft_from_moralis_metadata( - moralis_meta: Nft, + mut moralis_meta: Nft, transfer: &NftTransferHistory, my_address: &str, chain: &Chain, @@ -1184,10 +1208,13 @@ async fn create_nft_from_moralis_metadata( ) -> MmResult { let token_uri = check_moralis_ipfs_bafy(moralis_meta.common.token_uri.as_deref()); let token_domain = get_domain_from_url(token_uri.as_deref()); + check_token_uri(&mut moralis_meta.common.possible_spam, token_uri.as_deref())?; let uri_meta = get_uri_meta( token_uri.as_deref(), moralis_meta.common.metadata.as_deref(), url_antispam, + moralis_meta.common.possible_spam, + moralis_meta.possible_phishing, ) .await; let nft = Nft { @@ -1308,6 +1335,18 @@ where Ok(()) } +/// Checks if the given URL is potentially malicious based on certain patterns. +fn is_malicious(token_uri: &str) -> MmResult { + let patterns = vec![r"\.(xyz|gq|top)(/|$)", r"\.(json|xml|jpg|png)[%?]"]; + for pattern in patterns { + let regex = Regex::new(pattern)?; + if regex.is_match(token_uri) { + return Ok(true); + } + } + Ok(false) +} + /// `contains_disallowed_scheme` function checks if the text contains some link. fn contains_disallowed_url(text: &str) -> Result { let url_regex = Regex::new( @@ -1412,15 +1451,20 @@ fn process_metadata_field( async fn build_nft_from_moralis( chain: Chain, - nft_moralis: NftFromMoralis, + mut nft_moralis: NftFromMoralis, contract_type: ContractType, url_antispam: &Url, ) -> Nft { let token_uri = check_moralis_ipfs_bafy(nft_moralis.common.token_uri.as_deref()); + if let Err(e) = check_token_uri(&mut nft_moralis.common.possible_spam, token_uri.as_deref()) { + error!("Error checking token URI: {}", e); + } let uri_meta = get_uri_meta( token_uri.as_deref(), nft_moralis.common.metadata.as_deref(), url_antispam, + nft_moralis.common.possible_spam, + false, ) .await; let token_domain = get_domain_from_url(token_uri.as_deref()); diff --git a/mm2src/coins/nft/nft_errors.rs b/mm2src/coins/nft/nft_errors.rs index 8a6fb90f19..cf36b128b7 100644 --- a/mm2src/coins/nft/nft_errors.rs +++ b/mm2src/coins/nft/nft_errors.rs @@ -151,6 +151,7 @@ pub enum UpdateNftError { #[from_stringify("LockDBError")] #[display(fmt = "DB error {}", _0)] DbError(String), + #[from_stringify("regex::Error")] #[display(fmt = "Internal: {}", _0)] Internal(String), GetNftInfoError(GetNftInfoError), diff --git a/mm2src/coins/nft/nft_structs.rs b/mm2src/coins/nft/nft_structs.rs index 0096e8f2fe..155685d768 100644 --- a/mm2src/coins/nft/nft_structs.rs +++ b/mm2src/coins/nft/nft_structs.rs @@ -806,6 +806,7 @@ where #[derive(Debug, Deserialize)] pub struct ClearNftDbReq { /// Specifies the blockchain networks (e.g., Ethereum, BSC) to clear NFT data. + #[serde(default)] pub(crate) chains: Vec, /// If `true`, clears NFT data for all chains, ignoring the `chains` field. Defaults to `false`. #[serde(default)] diff --git a/mm2src/coins/nft/nft_tests.rs b/mm2src/coins/nft/nft_tests.rs index f0dd57603c..99fae76e1b 100644 --- a/mm2src/coins/nft/nft_tests.rs +++ b/mm2src/coins/nft/nft_tests.rs @@ -4,7 +4,7 @@ use crate::nft::nft_structs::{Chain, NftFromMoralis, NftListFilters, NftTransfer SpamContractRes, TransferMeta, UriMeta}; use crate::nft::storage::db_test_helpers::{get_nft_ctx, nft, nft_list, nft_transfer_history}; use crate::nft::storage::{NftListStorageOps, NftTransferHistoryStorageOps, RemoveNftResult}; -use crate::nft::{check_moralis_ipfs_bafy, get_domain_from_url, process_metadata_for_spam_link, +use crate::nft::{check_moralis_ipfs_bafy, get_domain_from_url, is_malicious, process_metadata_for_spam_link, process_text_for_spam_link}; use common::cross_test; use ethereum_types::Address; @@ -30,6 +30,14 @@ common::cfg_wasm32! { use mm2_net::wasm::http::send_request_to_uri; } +cross_test!(test_is_malicious, { + let token_uri = "https://btrgtrhbyjuyj.xyz/BABYDOGE.json"; + assert!(is_malicious(token_uri).unwrap()); + + let token_uri1 = "https://btrgtrhbyjuyj.com/BABYDOGE.json%00"; + assert!(is_malicious(token_uri1).unwrap()); +}); + cross_test!(test_moralis_ipfs_bafy, { let uri = "https://ipfs.moralis.io:2053/ipfs/bafybeifnek24coy5xj5qabdwh24dlp5omq34nzgvazkfyxgnqms4eidsiq/1.json"; let res_uri = check_moralis_ipfs_bafy(Some(uri)); From f9f4eab0c5f809a0060d3ec78954bae1c824e855 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 24 Apr 2024 16:57:39 +0700 Subject: [PATCH 009/233] doc comms --- mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs | 7 +++++-- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 2bf6c24411..11243d9a8a 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -95,8 +95,11 @@ pub static mut GETH_ERC1155_CONTRACT: H160Eth = H160Eth::zero(); pub static mut GETH_NFT_SWAP_CONTRACT: H160Eth = H160Eth::zero(); /// NFT Maker Swap V2 contract address on Geth dev node pub static mut GETH_NFT_MAKER_SWAP_V2: H160Eth = H160Eth::zero(); -pub static mut SEPOLIA_ETOMIC_MAKER_NFT_SWAP: H160Eth = H160Eth::zero(); +/// NFT Maker Swap V2 contract address on Sepolia testnet +pub static mut SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2: H160Eth = H160Eth::zero(); +/// ERC721 token address on Sepolia testnet pub static mut SEPOLIA_ERC721_CONTRACT: H160Eth = H160Eth::zero(); +/// ERC1155 token address on Sepolia testnet pub static mut SEPOLIA_ERC1155_CONTRACT: H160Eth = H160Eth::zero(); pub static GETH_RPC_URL: &str = "http://127.0.0.1:8545"; pub static SEPOLIA_RPC_URL: &str = "https://ethereum-sepolia-rpc.publicnode.com"; @@ -1412,7 +1415,7 @@ pub fn init_geth_node() { thread::sleep(Duration::from_millis(100)); } - SEPOLIA_ETOMIC_MAKER_NFT_SWAP = EthAddress::from_str("0x9eb88cd58605d8fb9b14652d6152727f7e95fb4d").unwrap(); + SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2 = EthAddress::from_str("0x9eb88cd58605d8fb9b14652d6152727f7e95fb4d").unwrap(); SEPOLIA_ERC721_CONTRACT = EthAddress::from_str("0xde3a479f463c17a6f0a4cbe67e506467e97e2c52").unwrap(); SEPOLIA_ERC1155_CONTRACT = EthAddress::from_str("0xfb53b8764be6033d89ceacafa36631b09d60a1d2").unwrap(); diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index a73bef9676..365f22b863 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -2,7 +2,7 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC7 GETH_ERC1155_CONTRACT, GETH_ERC20_CONTRACT, GETH_ERC721_CONTRACT, GETH_NFT_MAKER_SWAP_V2, GETH_NFT_SWAP_CONTRACT, GETH_NONCE_LOCK, GETH_RPC_URL, GETH_SWAP_CONTRACT, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, MM_CTX, - SEPOLIA_ERC1155_CONTRACT, SEPOLIA_ERC721_CONTRACT, SEPOLIA_ETOMIC_MAKER_NFT_SWAP, + SEPOLIA_ERC1155_CONTRACT, SEPOLIA_ERC721_CONTRACT, SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2, SEPOLIA_NONCE_LOCK, SEPOLIA_RPC_URL, SEPOLIA_WEB3}; use crate::common::Future01CompatExt; use bitcrypto::{dhash160, sha256}; @@ -77,8 +77,8 @@ pub fn erc1155_contract() -> Address { unsafe { GETH_ERC1155_CONTRACT } } /// # Safety /// -/// SEPOLIA_ETOMIC_MAKER_NFT_SWAP address is set once during initialization before tests start -pub fn sepolia_etomic_maker_nft() -> Address { unsafe { SEPOLIA_ETOMIC_MAKER_NFT_SWAP } } +/// SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2 address is set once during initialization before tests start +pub fn sepolia_etomic_maker_nft() -> Address { unsafe { SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2 } } /// # Safety /// From c703913112f3ccb4d00f1ac7b8771d0b899c83ec Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 26 Apr 2024 14:50:32 +0700 Subject: [PATCH 010/233] fix merge conflicts --- mm2src/coins/eth.rs | 2 +- .../tests/docker_tests/eth_docker_tests.rs | 27 ++++++++++--------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 41b2474870..0eee0b5356 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -3356,7 +3356,7 @@ impl EthCoin { #[cfg_attr(test, mockable)] impl EthCoin { - pub(crate) fn sign_and_send_transaction(&self, value: U256, action: Action, data: Vec, gas: U256) -> EthTxFut { + pub fn sign_and_send_transaction(&self, value: U256, action: Action, data: Vec, gas: U256) -> EthTxFut { let coin = self.clone(); let fut = async move { match coin.priv_key_policy { diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index dcb94495cd..59e6925607 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -225,7 +225,6 @@ pub(crate) fn erc1155_balance(wallet_addr: Address, token_id: U256) -> U256 { .unwrap() } -#[allow(dead_code)] pub(crate) async fn fill_erc1155_info(eth_coin: &EthCoin, token_address: Address, token_id: u32, amount: u32) { let nft_infos_lock = eth_coin.nfts_infos.clone(); let mut nft_infos = nft_infos_lock.lock().await; @@ -242,7 +241,6 @@ pub(crate) async fn fill_erc1155_info(eth_coin: &EthCoin, token_address: Address nft_infos.insert(erc1155_key, erc1155_nft_info); } -#[allow(dead_code)] pub(crate) async fn fill_erc721_info(eth_coin: &EthCoin, token_address: Address, token_id: u32) { let nft_infos_lock = eth_coin.nfts_infos.clone(); let mut nft_infos = nft_infos_lock.lock().await; @@ -425,6 +423,7 @@ fn global_nft_from_privkey( fn send_safe_transfer_from( global_nft: &EthCoin, token_address: Address, + from_address: Address, to_address: Address, nft_type: TestNftType, ) -> web3::Result { @@ -440,14 +439,14 @@ fn send_safe_transfer_from( }; let tokens = match nft_type { TestNftType::Erc1155 { token_id, amount } => vec![ - Token::Address(global_nft.my_address), + Token::Address(from_address), Token::Address(to_address), Token::Uint(U256::from(token_id)), Token::Uint(U256::from(amount)), Token::Bytes(vec![]), ], TestNftType::Erc721 { token_id } => vec![ - Token::Address(global_nft.my_address), + Token::Address(from_address), Token::Address(to_address), Token::Uint(U256::from(token_id)), ], @@ -903,14 +902,16 @@ fn send_and_spend_erc721_maker_payment() { taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); let new_owner = erc712_owner(U256::from(1)); - let my_address = block_on(taker_global_nft.my_addr()); - assert_eq!(new_owner, my_address); + let taker_address = block_on(taker_global_nft.my_addr()); + assert_eq!(new_owner, taker_address); // send nft back to maker + let maker_address = block_on(maker_global_nft.my_addr()); let send_back_tx = send_safe_transfer_from( &taker_global_nft, sepolia_erc721(), - maker_global_nft.my_address, + taker_address, + maker_address, erc721_nft, ) .unwrap(); @@ -924,7 +925,7 @@ fn send_and_spend_erc721_maker_payment() { taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); let new_owner = erc712_owner(U256::from(1)); - assert_eq!(new_owner, maker_global_nft.my_address); + assert_eq!(new_owner, maker_address); } #[test] @@ -1006,14 +1007,17 @@ fn send_and_spend_erc1155_maker_payment() { }; taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - let balance = erc1155_balance(taker_global_nft.my_address, U256::from(1)); + let taker_address = block_on(taker_global_nft.my_addr()); + let balance = erc1155_balance(taker_address, U256::from(1)); assert_eq!(balance, U256::from(3)); // send nft back to maker + let maker_address = block_on(maker_global_nft.my_addr()); let send_back_tx = send_safe_transfer_from( &taker_global_nft, sepolia_erc1155(), - maker_global_nft.my_address, + taker_address, + maker_address, erc1155_nft, ) .unwrap(); @@ -1026,8 +1030,7 @@ fn send_and_spend_erc1155_maker_payment() { }; taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - let my_address = block_on(taker_global_nft.my_addr()); - let balance = erc1155_balance(my_address, U256::from(1)); + let balance = erc1155_balance(maker_address, U256::from(1)); assert_eq!(balance, U256::from(3)); } From fe498fab4ef6f0ecd4b46983d51e149185e3ace8 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 26 Apr 2024 16:41:55 +0700 Subject: [PATCH 011/233] impl wait_pending_transactions --- .../tests/docker_tests/eth_docker_tests.rs | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 59e6925607..463bc21761 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -23,7 +23,7 @@ use std::thread; use std::time::Duration; use web3::contract::{Contract, Options}; use web3::ethabi::Token; -use web3::types::{Address, TransactionRequest, H256}; +use web3::types::{Address, BlockNumber, TransactionRequest, H256}; const SEPOLIA_MAKER_PRIV: &str = "6e2f3a6223b928a05a3a3622b0c3f3573d03663b704a61a6eb73326de0487928"; const SEPOLIA_TAKER_PRIV: &str = "e0be82dca60ff7e4c6d6db339ac9e1ae249af081dba2110bddd281e711608f16"; @@ -817,13 +817,30 @@ fn send_and_spend_erc20_maker_payment() { assert_eq!(expected, search_tx); } +/// Wait for all pending transactions for the given address to be confirmed +fn wait_pending_transactions(wallet_address: Address) { + let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); + let web3 = SEPOLIA_WEB3.clone(); + + loop { + let latest_nonce = block_on(web3.eth().transaction_count(wallet_address, Some(BlockNumber::Latest))).unwrap(); + let pending_nonce = block_on(web3.eth().transaction_count(wallet_address, Some(BlockNumber::Pending))).unwrap(); + + if latest_nonce == pending_nonce { + println!("All pending transactions have been confirmed."); + break; + } else { + println!( + "Waiting for pending transactions to confirm... Current nonce: {}, Pending nonce: {}", + latest_nonce, pending_nonce + ); + thread::sleep(Duration::from_secs(5)); + } + } +} + #[test] fn send_and_spend_erc721_maker_payment() { - // TODO: Evaluate implementation strategy — either employing separate contracts for maker and taker - // functionalities for both coins and NFTs, or utilizing the Diamond Standard (EIP-2535) for a unified contract approach. - // Decision will inform whether to maintain multiple "swap_contract_address" fields in `EthCoin` for distinct contract types - // or a singular field for a Diamond Standard-compatible contract address. - // Sepolia Maker owns tokenId = 1 let erc721_nft = TestNftType::Erc721 { token_id: 1 }; @@ -831,6 +848,9 @@ fn send_and_spend_erc721_maker_payment() { let maker_global_nft = global_nft_from_privkey(sepolia_etomic_maker_nft(), SEPOLIA_MAKER_PRIV, Some(erc721_nft)); let taker_global_nft = global_nft_from_privkey(sepolia_etomic_maker_nft(), SEPOLIA_TAKER_PRIV, None); + let maker_address = block_on(maker_global_nft.my_addr()); + wait_pending_transactions(maker_address); + let time_lock = now_sec() + 1000; let maker_pubkey = maker_global_nft.derive_htlc_pubkey(&[]); let taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); @@ -906,7 +926,6 @@ fn send_and_spend_erc721_maker_payment() { assert_eq!(new_owner, taker_address); // send nft back to maker - let maker_address = block_on(maker_global_nft.my_addr()); let send_back_tx = send_safe_transfer_from( &taker_global_nft, sepolia_erc721(), From 18fa53e8487306548f1077524f895b133487dcc0 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 26 Apr 2024 22:32:14 +0700 Subject: [PATCH 012/233] increase max nonce by 1 --- mm2src/coins/eth.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 0eee0b5356..f17c02e01b 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -5074,11 +5074,12 @@ impl EthCoin { return ERR!("Couldn't get nonce after 5 errored attempts, aborting"); } } else { - let max = nonces + let mut max = nonces .iter() .map(|(n, _)| *n) .max() .expect("nonces should not be empty!"); + max = max + 1; break Ok(( max, nonces From b9a6719c879253f34a5f1f8fe65a98cb3d2e46a0 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 26 Apr 2024 22:55:54 +0700 Subject: [PATCH 013/233] Revert "increase max nonce by 1" This reverts commit 18fa53e8487306548f1077524f895b133487dcc0. --- mm2src/coins/eth.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index f17c02e01b..0eee0b5356 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -5074,12 +5074,11 @@ impl EthCoin { return ERR!("Couldn't get nonce after 5 errored attempts, aborting"); } } else { - let mut max = nonces + let max = nonces .iter() .map(|(n, _)| *n) .max() .expect("nonces should not be empty!"); - max = max + 1; break Ok(( max, nonces From 998708bd6582f89d2ff634c888bba034f1175834 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 29 Apr 2024 14:54:17 +0700 Subject: [PATCH 014/233] impl get_or_create_nft function --- mm2src/coins/lp_coins.rs | 4 +- .../tests/docker_tests/docker_tests_common.rs | 1 + .../tests/docker_tests/eth_docker_tests.rs | 43 ++++++++++++++----- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 9b6c465f7b..7de8feea8c 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -3398,7 +3398,7 @@ pub struct MmCoinStruct { } impl MmCoinStruct { - fn new(coin: MmCoinEnum) -> Self { + pub fn new(coin: MmCoinEnum) -> Self { Self { inner: coin, is_available: AtomicBool::new(true).into(), @@ -3501,7 +3501,7 @@ impl DexFee { pub struct CoinsContext { /// A map from a currency ticker symbol to the corresponding coin. /// Similar to `LP_coins`. - coins: AsyncMutex>, + pub coins: AsyncMutex>, balance_update_handlers: AsyncMutex>>, account_balance_task_manager: AccountBalanceTaskManagerShared, create_account_manager: CreateAccountTaskManagerShared, diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 77628700de..f834175661 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -67,6 +67,7 @@ lazy_static! { // Supply more privkeys when 18 will be not enough. pub static ref SLP_TOKEN_OWNERS: Mutex> = Mutex::new(Vec::with_capacity(18)); pub static ref MM_CTX: MmArc = MmCtxBuilder::new().into_mm_arc(); + pub static ref MM_CTX1: MmArc = MmCtxBuilder::new().into_mm_arc(); pub static ref GETH_WEB3: Web3 = Web3::new(Http::new(GETH_RPC_URL).unwrap()); pub static ref SEPOLIA_WEB3: Web3 = Web3::new(Http::new(SEPOLIA_RPC_URL).unwrap()); // Mutex used to prevent nonce re-usage during funding addresses used in tests diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 463bc21761..ea470970d9 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1,7 +1,7 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC721_TEST_ABI, GETH_ACCOUNT, GETH_ERC1155_CONTRACT, GETH_ERC20_CONTRACT, GETH_ERC721_CONTRACT, GETH_NFT_MAKER_SWAP_V2, GETH_NFT_SWAP_CONTRACT, GETH_NONCE_LOCK, GETH_RPC_URL, - GETH_SWAP_CONTRACT, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, MM_CTX, + GETH_SWAP_CONTRACT, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, MM_CTX, MM_CTX1, SEPOLIA_ERC1155_CONTRACT, SEPOLIA_ERC721_CONTRACT, SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2, SEPOLIA_NONCE_LOCK, SEPOLIA_RPC_URL, SEPOLIA_WEB3}; use crate::common::Future01CompatExt; @@ -9,14 +9,16 @@ use bitcrypto::{dhash160, sha256}; use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_request, Action, EthCoin, SignedEthTx, ERC20_ABI}; use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; -use coins::{CoinProtocol, CoinWithDerivationMethod, ConfirmPaymentInput, DerivationMethod, FoundSwapTxSpend, - MakerNftSwapOpsV2, MarketCoinOps, NftSwapInfo, ParseCoinAssocTypes, PrivKeyBuildPolicy, RefundPaymentArgs, - SearchForSwapTxSpendInput, SendNftMakerPaymentArgs, SendPaymentArgs, SpendNftMakerPaymentArgs, - SpendPaymentArgs, SwapOps, SwapTxTypeWithSecretHash, ToBytes, Transaction, ValidateNftMakerPaymentArgs}; +use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, ConfirmPaymentInput, DerivationMethod, + FoundSwapTxSpend, MakerNftSwapOpsV2, MarketCoinOps, MmCoinEnum, MmCoinStruct, NftSwapInfo, + ParseCoinAssocTypes, PrivKeyBuildPolicy, RefundPaymentArgs, SearchForSwapTxSpendInput, + SendNftMakerPaymentArgs, SendPaymentArgs, SpendNftMakerPaymentArgs, SpendPaymentArgs, SwapOps, + SwapTxTypeWithSecretHash, ToBytes, Transaction, ValidateNftMakerPaymentArgs}; use common::{block_on, now_sec}; use crypto::Secp256k1Secret; use ethereum_types::U256; use futures01::Future; +use mm2_core::mm_ctx::MmArc; use mm2_number::{BigDecimal, BigUint}; use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, nft_dev_conf, nft_sepolia_conf}; use std::thread; @@ -27,6 +29,7 @@ use web3::types::{Address, BlockNumber, TransactionRequest, H256}; const SEPOLIA_MAKER_PRIV: &str = "6e2f3a6223b928a05a3a3622b0c3f3573d03663b704a61a6eb73326de0487928"; const SEPOLIA_TAKER_PRIV: &str = "e0be82dca60ff7e4c6d6db339ac9e1ae249af081dba2110bddd281e711608f16"; +const NFT_ETH: &str = "NFT_ETH"; /// # Safety /// @@ -381,6 +384,7 @@ pub fn global_nft_with_random_privkey(swap_contract_address: Address, nft_type: } fn global_nft_from_privkey( + ctx: &MmArc, swap_contract_address: Address, secret: &'static str, nft_type: Option, @@ -395,8 +399,8 @@ fn global_nft_from_privkey( let priv_key = Secp256k1Secret::from(secret); let global_nft = block_on(eth_coin_from_conf_and_request( - &MM_CTX, - "NFT_ETH", + ctx, + NFT_ETH, &nft_conf, &req, CoinProtocol::NFT { @@ -406,6 +410,13 @@ fn global_nft_from_privkey( )) .unwrap(); + let coins_ctx = CoinsContext::from_ctx(ctx).unwrap(); + let mut coins = block_on(coins_ctx.coins.lock()); + coins.insert( + global_nft.ticker().into(), + MmCoinStruct::new(MmCoinEnum::EthCoin(global_nft.clone())), + ); + if let Some(nft_type) = nft_type { match nft_type { TestNftType::Erc1155 { token_id, amount } => { @@ -839,14 +850,24 @@ fn wait_pending_transactions(wallet_address: Address) { } } +fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option) -> EthCoin { + match block_on(lp_coinfind(ctx, NFT_ETH)).unwrap() { + None => global_nft_from_privkey(ctx, sepolia_etomic_maker_nft(), priv_key, nft_type), + Some(mm_coin) => match mm_coin { + MmCoinEnum::EthCoin(nft) => nft, + _ => panic!("Unexpected coin type found. Expected MmCoinEnum::EthCoin"), + }, + } +} + #[test] fn send_and_spend_erc721_maker_payment() { // Sepolia Maker owns tokenId = 1 let erc721_nft = TestNftType::Erc721 { token_id: 1 }; - let maker_global_nft = global_nft_from_privkey(sepolia_etomic_maker_nft(), SEPOLIA_MAKER_PRIV, Some(erc721_nft)); - let taker_global_nft = global_nft_from_privkey(sepolia_etomic_maker_nft(), SEPOLIA_TAKER_PRIV, None); + let maker_global_nft = get_or_create_nft(&MM_CTX, SEPOLIA_MAKER_PRIV, Some(erc721_nft)); + let taker_global_nft = get_or_create_nft(&MM_CTX1, SEPOLIA_TAKER_PRIV, None); let maker_address = block_on(maker_global_nft.my_addr()); wait_pending_transactions(maker_address); @@ -953,8 +974,8 @@ fn send_and_spend_erc1155_maker_payment() { let erc1155_nft = TestNftType::Erc1155 { token_id: 1, amount: 3 }; - let maker_global_nft = global_nft_from_privkey(sepolia_etomic_maker_nft(), SEPOLIA_MAKER_PRIV, Some(erc1155_nft)); - let taker_global_nft = global_nft_from_privkey(sepolia_etomic_maker_nft(), SEPOLIA_TAKER_PRIV, None); + let maker_global_nft = get_or_create_nft(&MM_CTX, SEPOLIA_MAKER_PRIV, Some(erc1155_nft)); + let taker_global_nft = get_or_create_nft(&MM_CTX1, SEPOLIA_TAKER_PRIV, None); let time_lock = now_sec() + 1000; let maker_pubkey = maker_global_nft.derive_htlc_pubkey(&[]); From 364d795f60d8e9539fdec6331f58ed27c52b56cd Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 29 Apr 2024 16:11:28 +0700 Subject: [PATCH 015/233] additional logs, ignore erc1155 --- .../tests/docker_tests/eth_docker_tests.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index ea470970d9..3f7dddd956 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -854,7 +854,10 @@ fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option global_nft_from_privkey(ctx, sepolia_etomic_maker_nft(), priv_key, nft_type), Some(mm_coin) => match mm_coin { - MmCoinEnum::EthCoin(nft) => nft, + MmCoinEnum::EthCoin(nft) => { + println!("Found EthCoin {:?}", nft.ticker()); + nft + }, _ => panic!("Unexpected coin type found. Expected MmCoinEnum::EthCoin"), }, } @@ -867,7 +870,11 @@ fn send_and_spend_erc721_maker_payment() { let erc721_nft = TestNftType::Erc721 { token_id: 1 }; let maker_global_nft = get_or_create_nft(&MM_CTX, SEPOLIA_MAKER_PRIV, Some(erc721_nft)); + let maker_addr = block_on(maker_global_nft.my_addr()); + println!("maker_addr {:?}\n", maker_addr); let taker_global_nft = get_or_create_nft(&MM_CTX1, SEPOLIA_TAKER_PRIV, None); + let taker_addr = block_on(taker_global_nft.my_addr()); + println!("taker_addr {:?}\n", taker_addr); let maker_address = block_on(maker_global_nft.my_addr()); wait_pending_transactions(maker_address); @@ -896,7 +903,11 @@ fn send_and_spend_erc721_maker_payment() { nft_swap_info: &nft_swap_info, }; let maker_payment = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); - log!("Maker sent ERC721 NFT Payment tx hash {:02x}", maker_payment.tx_hash()); + log!( + "Maker sent ERC721 NFT Payment tx hash {:02x}\n", + maker_payment.tx_hash() + ); + log!("Maker ERC721 NFT Payment transaction\n", maker_payment); let confirm_input = ConfirmPaymentInput { payment_tx: maker_payment.tx_hex(), @@ -969,6 +980,7 @@ fn send_and_spend_erc721_maker_payment() { } #[test] +#[ignore] fn send_and_spend_erc1155_maker_payment() { // Sepolia Maker owns tokenId = 1, amount = 3 From cb187c78f4951d88c297b2a26b3f5adee03ee4dc Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 29 Apr 2024 16:26:27 +0700 Subject: [PATCH 016/233] deploy new SEPOLIA_ERC721_CONTRACT --- mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index f834175661..a9f0e97eb7 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -1384,7 +1384,7 @@ pub fn init_geth_node() { } SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2 = EthAddress::from_str("0x9eb88cd58605d8fb9b14652d6152727f7e95fb4d").unwrap(); - SEPOLIA_ERC721_CONTRACT = EthAddress::from_str("0xde3a479f463c17a6f0a4cbe67e506467e97e2c52").unwrap(); + SEPOLIA_ERC721_CONTRACT = EthAddress::from_str("0xbac1c9f2087f39caaa4e93412c6412809186870e").unwrap(); SEPOLIA_ERC1155_CONTRACT = EthAddress::from_str("0xfb53b8764be6033d89ceacafa36631b09d60a1d2").unwrap(); let alice_passphrase = get_passphrase!(".env.client", "ALICE_PASSPHRASE").unwrap(); From 9d4e3ee0f127201dccb70a882fdf825c75d1a897 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 29 Apr 2024 16:33:51 +0700 Subject: [PATCH 017/233] fix linter --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 3f7dddd956..85ea7986b3 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -907,7 +907,7 @@ fn send_and_spend_erc721_maker_payment() { "Maker sent ERC721 NFT Payment tx hash {:02x}\n", maker_payment.tx_hash() ); - log!("Maker ERC721 NFT Payment transaction\n", maker_payment); + log!("Maker ERC721 NFT Payment transaction\n{:?}", maker_payment); let confirm_input = ConfirmPaymentInput { payment_tx: maker_payment.tx_hex(), From 495e7a9a059caec93ab009b36fbc5f9621582327 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 29 Apr 2024 17:18:55 +0700 Subject: [PATCH 018/233] run both nft send payment tests --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 85ea7986b3..d1e0daacf5 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -980,7 +980,6 @@ fn send_and_spend_erc721_maker_payment() { } #[test] -#[ignore] fn send_and_spend_erc1155_maker_payment() { // Sepolia Maker owns tokenId = 1, amount = 3 From e917b0b50544fa35310bc869c3defe7ee4f3ee1b Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 6 May 2024 21:21:10 +0700 Subject: [PATCH 019/233] proxy: send nft reqs with payload data in body to satisfy proxy HttpGetPayload format, add body: Option for wasm target request, None payload in tests --- mm2src/coins/eth.rs | 2 +- mm2src/coins/eth/v2_activation.rs | 29 ++- mm2src/coins/nft.rs | 208 ++++++++++++++---- mm2src/coins/nft/nft_errors.rs | 16 +- mm2src/coins/nft/nft_tests.rs | 8 +- .../src/erc20_token_activation.rs | 1 + .../src/eth_with_token_activation.rs | 1 + .../src/init_erc20_token_activation.rs | 6 +- mm2src/coins_activation/src/token.rs | 8 +- .../tests/docker_tests/eth_docker_tests.rs | 9 +- mm2src/mm2_net/src/native_http.rs | 9 +- mm2src/mm2_net/src/wasm/http.rs | 11 +- 12 files changed, 238 insertions(+), 70 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 0eee0b5356..caccc4b4ae 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -466,7 +466,7 @@ impl From for EthPrivKeyBuildPolicy { pub struct EthCoinImpl { ticker: String, pub coin_type: EthCoinType, - priv_key_policy: EthPrivKeyPolicy, + pub(crate) priv_key_policy: EthPrivKeyPolicy, /// Either an Iguana address or a 'EthHDWallet' instance. /// Arc is used to use the same hd wallet from platform coin if we need to. /// This allows the reuse of the same derived accounts/addresses of the diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 5a79e19f9e..b1de7fe1bd 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -89,6 +89,7 @@ impl From for EthActivationV2Error { EthTokenActivationError::UnexpectedDerivationMethod(err) => { EthActivationV2Error::UnexpectedDerivationMethod(err) }, + EthTokenActivationError::PrivKeyPolicyNotAllowed(e) => EthActivationV2Error::PrivKeyPolicyNotAllowed(e), } } } @@ -210,6 +211,7 @@ pub enum EthTokenActivationError { InvalidPayload(String), Transport(String), UnexpectedDerivationMethod(UnexpectedDerivationMethod), + PrivKeyPolicyNotAllowed(PrivKeyPolicyNotAllowed), } impl From for EthTokenActivationError { @@ -256,6 +258,10 @@ impl From for EthTokenActivationError { fn from(e: ParseChainTypeError) -> Self { EthTokenActivationError::InternalError(e.to_string()) } } +impl From for EthTokenActivationError { + fn from(e: PrivKeyPolicyNotAllowed) -> Self { EthTokenActivationError::PrivKeyPolicyNotAllowed(e) } +} + /// Represents the parameters required for activating either an ERC-20 token or an NFT on the Ethereum platform. #[derive(Clone, Deserialize)] #[serde(untagged)] @@ -433,7 +439,10 @@ impl EthCoin { /// It fetches NFT details from a given URL to populate the `nfts_infos` field, which stores information about the user's NFTs. /// /// This setup allows the Global NFT to function like a coin, supporting swap operations and providing easy access to NFT details via `nfts_infos`. - pub async fn global_nft_from_platform_coin(&self, url: &Url) -> MmResult { + pub async fn global_nft_from_platform_coin( + &self, + original_url: &Url, + ) -> MmResult { let chain = Chain::from_ticker(self.ticker())?; let ticker = chain.to_nft_ticker().to_string(); @@ -443,7 +452,23 @@ impl EthCoin { // Todo: support HD wallet for NFTs, currently we get nfts for enabled address only and there might be some issues when activating NFTs while ETH is activated with HD wallet let my_address = self.derivation_method.single_addr_or_err().await?; - let nft_infos = get_nfts_for_activation(&chain, &my_address, url).await?; + let my_address_str = display_eth_address(&my_address); + let secret = self.priv_key_policy().activated_key_or_err()?.secret().clone(); + let validation_generator = GuiAuthValidationGenerator { + coin_ticker: chain.to_nft_ticker().to_string(), + secret, + address: my_address_str, + }; + let signed_message = match EthCoin::generate_gui_auth_signed_validation(validation_generator) { + Ok(t) => t, + Err(e) => { + return MmError::err(EthTokenActivationError::InternalError(format!( + "GuiAuth signed message generation failed. Error: {:?}", + e + ))) + }, + }; + let nft_infos = get_nfts_for_activation(&chain, &my_address, original_url, &signed_message).await?; let global_nft = EthCoinImpl { ticker, diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index 018ef12f9e..6ce96276b7 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -16,7 +16,7 @@ use nft_structs::{Chain, ContractType, ConvertChain, Nft, NftFromMoralis, NftLis TransactionNftDetails, UpdateNftReq, WithdrawNftReq}; use crate::eth::{eth_addr_to_hex, get_eth_address, withdraw_erc1155, withdraw_erc721, EthCoin, EthCoinType, - EthTxFeeDetails}; + EthTxFeeDetails, GuiAuthMessages}; use crate::hd_wallet::HDPathAccountToAddressId; use crate::nft::nft_errors::{ClearNftDbError, MetaFromUrlError, ProtectFromSpamError, TransferConfirmationsError, UpdateSpamPhishingError}; @@ -26,11 +26,12 @@ use crate::nft::nft_structs::{build_nft_with_empty_meta, BuildNftFields, ClearNf use crate::nft::storage::{NftListStorageOps, NftTransferHistoryStorageOps}; use common::log::error; use common::parse_rfc3339_to_timestamp; +use enum_derives::EnumFromStringify; use ethereum_types::{Address, H256}; use futures::compat::Future01CompatExt; use futures::future::try_join_all; use mm2_err_handle::map_to_mm::MapToMmResult; -use mm2_net::transport::send_post_request_to_uri; +use mm2_net::transport::{send_post_request_to_uri, GuiAuthValidation, GuiAuthValidationGenerator}; use mm2_number::BigUint; use regex::Regex; use serde::Deserialize; @@ -226,6 +227,7 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft NftTransferHistoryStorageOps::init(&storage, chain).await?; None }; + // TODO activate and use global NFT instead of ETH coin after adding enable nft using coin conf support let coin_enum = lp_coinfind_or_err(&ctx, chain.to_ticker()).await?; let eth_coin = match coin_enum { MmCoinEnum::EthCoin(eth_coin) => eth_coin, @@ -235,16 +237,37 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft }) }, }; - let nft_transfers = get_moralis_nft_transfers(&ctx, chain, from_block, &req.url, eth_coin).await?; + let my_address = eth_coin.my_address()?; + let secret = eth_coin.priv_key_policy.activated_key_or_err()?.secret().clone(); + + let validation_generator = GuiAuthValidationGenerator { + coin_ticker: chain.to_nft_ticker().to_string(), + secret, + address: my_address, + }; + let signed_message = match EthCoin::generate_gui_auth_signed_validation(validation_generator) { + Ok(t) => t, + Err(e) => { + return MmError::err(UpdateNftError::Internal(format!( + "GuiAuth signed message generation failed. Error: {:?}", + e + ))) + }, + }; + + let nft_transfers = + get_moralis_nft_transfers(&ctx, chain, from_block, &req.url, eth_coin, &signed_message).await?; storage.add_transfers_to_history(*chain, nft_transfers).await?; let nft_block = match NftListStorageOps::get_last_block_number(&storage, chain).await { Ok(Some(block)) => block, Ok(None) => { // if there are no rows in NFT LIST table we can try to get nft list from moralis. - let nft_list = cache_nfts_from_moralis(&ctx, &storage, chain, &req.url, &req.url_antispam).await?; + let nft_list = + cache_nfts_from_moralis(&ctx, &storage, chain, &req.url, &req.url_antispam, &signed_message) + .await?; update_meta_in_transfers(&storage, chain, nft_list).await?; - update_transfers_with_empty_meta(&storage, chain, &req.url, &req.url_antispam).await?; + update_transfers_with_empty_meta(&storage, chain, &req.url, &req.url_antispam, &signed_message).await?; update_spam(&storage, *chain, &req.url_antispam).await?; update_phishing(&storage, chain, &req.url_antispam).await?; continue; @@ -252,9 +275,11 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft Err(_) => { // if there is an error, then NFT LIST table doesnt exist, so we need to cache nft list from moralis. NftListStorageOps::init(&storage, chain).await?; - let nft_list = cache_nfts_from_moralis(&ctx, &storage, chain, &req.url, &req.url_antispam).await?; + let nft_list = + cache_nfts_from_moralis(&ctx, &storage, chain, &req.url, &req.url_antispam, &signed_message) + .await?; update_meta_in_transfers(&storage, chain, nft_list).await?; - update_transfers_with_empty_meta(&storage, chain, &req.url, &req.url_antispam).await?; + update_transfers_with_empty_meta(&storage, chain, &req.url, &req.url_antispam, &signed_message).await?; update_spam(&storage, *chain, &req.url_antispam).await?; update_phishing(&storage, chain, &req.url_antispam).await?; continue; @@ -282,10 +307,11 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft scanned_block + 1, &req.url, &req.url_antispam, + &signed_message, ) .await?; update_nft_global_in_coins_ctx(&ctx, &storage, *chain).await?; - update_transfers_with_empty_meta(&storage, chain, &req.url, &req.url_antispam).await?; + update_transfers_with_empty_meta(&storage, chain, &req.url, &req.url_antispam, &signed_message).await?; update_spam(&storage, *chain, &req.url_antispam).await?; update_phishing(&storage, chain, &req.url_antispam).await?; } @@ -458,6 +484,35 @@ pub async fn refresh_nft_metadata(ctx: MmArc, req: RefreshMetadataReq) -> MmResu let nft_ctx = NftCtx::from_ctx(&ctx).map_to_mm(GetNftInfoError::Internal)?; let storage = nft_ctx.lock_db().await?; + + // TODO activate and use global NFT instead of ETH coin after adding enable nft using coin conf support + let coin_enum = lp_coinfind_or_err(&ctx, req.chain.to_ticker()).await?; + let eth_coin = match coin_enum { + MmCoinEnum::EthCoin(eth_coin) => eth_coin, + _ => { + return MmError::err(UpdateNftError::CoinDoesntSupportNft { + coin: coin_enum.ticker().to_owned(), + }) + }, + }; + let my_address = eth_coin.my_address()?; + let secret = eth_coin.priv_key_policy.activated_key_or_err()?.secret().clone(); + + let validation_generator = GuiAuthValidationGenerator { + coin_ticker: req.chain.to_nft_ticker().to_string(), + secret, + address: my_address, + }; + let signed_message = match EthCoin::generate_gui_auth_signed_validation(validation_generator) { + Ok(t) => t, + Err(e) => { + return MmError::err(UpdateNftError::Internal(format!( + "GuiAuth signed message generation failed. Error: {:?}", + e + ))) + }, + }; + let token_address_str = eth_addr_to_hex(&req.token_address); let mut moralis_meta = match get_moralis_metadata( token_address_str.clone(), @@ -465,6 +520,7 @@ pub async fn refresh_nft_metadata(ctx: MmArc, req: RefreshMetadataReq) -> MmResu &req.chain, &req.url, &req.url_antispam, + &signed_message, ) .await { @@ -609,20 +665,26 @@ where async fn get_moralis_nft_list( ctx: &MmArc, chain: &Chain, - url: &Url, + original_url: &Url, url_antispam: &Url, + signed_message: &GuiAuthValidation, ) -> MmResult, GetNftInfoError> { let mut res_list = Vec::new(); let ticker = chain.to_ticker(); let conf = coin_conf(ctx, ticker); let my_address = get_eth_address(ctx, &conf, ticker, &HDPathAccountToAddressId::default()).await?; - let uri_without_cursor = construct_moralis_uri_for_nft(url, &my_address.wallet_address, chain)?; + let uri_without_cursor = construct_moralis_uri_for_nft(original_url, &my_address.wallet_address, chain)?; // The cursor returned in the previous response (used for getting the next page). let mut cursor = String::new(); loop { - let uri = format!("{}{}", uri_without_cursor, cursor); - let response = send_request_to_uri(uri.as_str()).await?; + // Create a new URL instance from uri_without_cursor and modify its query to include the cursor if present + let mut uri = uri_without_cursor.clone(); + if !cursor.is_empty() { + uri.set_query(Some(&cursor)); + } + let payload = http_get_payload_str(uri, signed_message.clone())?; + let response = send_request_to_uri(original_url.as_str(), Some(payload)).await?; if let Some(nfts_list) = response["result"].as_array() { for nft_json in nfts_list { let nft_moralis = NftFromMoralis::deserialize(nft_json)?; @@ -638,7 +700,7 @@ async fn get_moralis_nft_list( // if cursor is not null, there are other NFTs on next page, // and we need to send new request with cursor to get info from the next page. if let Some(cursor_res) = response["cursor"].as_str() { - cursor = format!("{}{}", "&cursor=", cursor_res); + cursor = format!("cursor={}", cursor_res); continue; } else { break; @@ -653,22 +715,28 @@ async fn get_moralis_nft_list( pub(crate) async fn get_nfts_for_activation( chain: &Chain, my_address: &Address, - url: &Url, + original_url: &Url, + signed_message: &GuiAuthValidation, ) -> MmResult, GetNftInfoError> { let mut nfts_map = HashMap::new(); - let uri_without_cursor = construct_moralis_uri_for_nft(url, ð_addr_to_hex(my_address), chain)?; + let uri_without_cursor = construct_moralis_uri_for_nft(original_url, ð_addr_to_hex(my_address), chain)?; // The cursor returned in the previous response (used for getting the next page). let mut cursor = String::new(); loop { - let uri = format!("{}{}", uri_without_cursor, cursor); - let response = send_request_to_uri(uri.as_str()).await?; + // Create a new URL instance from uri_without_cursor and modify its query to include the cursor if present + let mut uri = uri_without_cursor.clone(); + if !cursor.is_empty() { + uri.set_query(Some(&cursor)); + } + let payload = http_get_payload_str(uri, signed_message.clone())?; + let response = send_request_to_uri(original_url.as_str(), Some(payload)).await?; if let Some(nfts_list) = response["result"].as_array() { process_nft_list_for_activation(nfts_list, chain, &mut nfts_map)?; // if cursor is not null, there are other NFTs on next page, // and we need to send new request with cursor to get info from the next page. if let Some(cursor_res) = response["cursor"].as_str() { - cursor = format!("{}{}", "&cursor=", cursor_res); + cursor = format!("cursor={}", cursor_res); continue; } else { break; @@ -709,15 +777,16 @@ async fn get_moralis_nft_transfers( ctx: &MmArc, chain: &Chain, from_block: Option, - url: &Url, + original_url: &Url, eth_coin: EthCoin, + signed_message: &GuiAuthValidation, ) -> MmResult, GetNftInfoError> { let mut res_list = Vec::new(); let ticker = chain.to_ticker(); let conf = coin_conf(ctx, ticker); let my_address = get_eth_address(ctx, &conf, ticker, &HDPathAccountToAddressId::default()).await?; - let mut uri_without_cursor = url.clone(); + let mut uri_without_cursor = original_url.clone(); uri_without_cursor.set_path(MORALIS_API_ENDPOINT); uri_without_cursor .path_segments_mut() @@ -740,14 +809,19 @@ async fn get_moralis_nft_transfers( let mut cursor = String::new(); let wallet_address = my_address.wallet_address; loop { - let uri = format!("{}{}", uri_without_cursor, cursor); - let response = send_request_to_uri(uri.as_str()).await?; + // Create a new URL instance from uri_without_cursor and modify its query to include the cursor if present + let mut uri = uri_without_cursor.clone(); + if !cursor.is_empty() { + uri.set_query(Some(&cursor)); + } + let payload = http_get_payload_str(uri, signed_message.clone())?; + let response = send_request_to_uri(original_url.as_str(), Some(payload)).await?; if let Some(transfer_list) = response["result"].as_array() { process_transfer_list(transfer_list, chain, wallet_address.as_str(), ð_coin, &mut res_list).await?; // if the cursor is not null, there are other NFTs transfers on next page, // and we need to send new request with cursor to get info from the next page. if let Some(cursor_res) = response["cursor"].as_str() { - cursor = format!("{}{}", "&cursor=", cursor_res); + cursor = format!("cursor={}", cursor_res); continue; } else { break; @@ -858,10 +932,11 @@ async fn get_moralis_metadata( token_address: String, token_id: BigUint, chain: &Chain, - url: &Url, + original_url: &Url, url_antispam: &Url, + signed_message: &GuiAuthValidation, ) -> MmResult { - let mut uri = url.clone(); + let mut uri = original_url.clone(); uri.set_path(MORALIS_API_ENDPOINT); uri.path_segments_mut() .map_to_mm(|_| GetNftInfoError::Internal("Invalid URI".to_string()))? @@ -873,7 +948,8 @@ async fn get_moralis_metadata( .append_pair(MORALIS_FORMAT_QUERY_NAME, MORALIS_FORMAT_QUERY_VALUE); drop_mutability!(uri); - let response = send_request_to_uri(uri.as_str()).await?; + let payload = http_get_payload_str(uri, signed_message.clone())?; + let response = send_request_to_uri(original_url.as_str(), Some(payload)).await?; let nft_moralis: NftFromMoralis = serde_json::from_str(&response.to_string())?; let contract_type = match nft_moralis.contract_type { Some(contract_type) => contract_type, @@ -951,7 +1027,7 @@ fn construct_camo_url_with_token(token_uri: &str, url_antispam: &Url) -> Option< } async fn fetch_meta_from_url(url: Url) -> MmResult { - let response_meta = send_request_to_uri(url.as_str()).await?; + let response_meta = send_request_to_uri(url.as_str(), None).await?; serde_json::from_value(response_meta).map_err(|e| e.into()) } @@ -980,8 +1056,9 @@ async fn update_nft_list( storage: &T, chain: &Chain, scan_from_block: u64, - url: &Url, + original_url: &Url, url_antispam: &Url, + signed_message: &GuiAuthValidation, ) -> MmResult<(), UpdateNftError> { let transfers = storage.get_transfers_from_block(*chain, scan_from_block).await?; let req = MyAddressReq { @@ -990,7 +1067,16 @@ async fn update_nft_list( }; let my_address = get_my_address(ctx.clone(), req).await?.wallet_address.to_lowercase(); for transfer in transfers.into_iter() { - handle_nft_transfer(storage, chain, url, url_antispam, transfer, &my_address).await?; + handle_nft_transfer( + storage, + chain, + original_url, + url_antispam, + signed_message, + transfer, + &my_address, + ) + .await?; } Ok(()) } @@ -998,19 +1084,38 @@ async fn update_nft_list( async fn handle_nft_transfer( storage: &T, chain: &Chain, - url: &Url, + original_url: &Url, url_antispam: &Url, + signed_message: &GuiAuthValidation, transfer: NftTransferHistory, my_address: &str, ) -> MmResult<(), UpdateNftError> { match (transfer.status, transfer.contract_type) { (TransferStatus::Send, ContractType::Erc721) => handle_send_erc721(storage, chain, transfer).await, (TransferStatus::Receive, ContractType::Erc721) => { - handle_receive_erc721(storage, chain, transfer, url, url_antispam, my_address).await + handle_receive_erc721( + storage, + chain, + transfer, + original_url, + url_antispam, + signed_message, + my_address, + ) + .await }, (TransferStatus::Send, ContractType::Erc1155) => handle_send_erc1155(storage, chain, transfer).await, (TransferStatus::Receive, ContractType::Erc1155) => { - handle_receive_erc1155(storage, chain, transfer, url, url_antispam, my_address).await + handle_receive_erc1155( + storage, + chain, + transfer, + original_url, + url_antispam, + signed_message, + my_address, + ) + .await }, } } @@ -1046,8 +1151,9 @@ async fn handle_receive_erc721 MmResult<(), UpdateNftError> { let token_address_str = eth_addr_to_hex(&transfer.common.token_address); @@ -1074,8 +1180,9 @@ async fn handle_receive_erc721 MmResult<(), UpdateNftError> { let token_address_str = eth_addr_to_hex(&transfer.common.token_address); @@ -1167,8 +1275,9 @@ async fn handle_receive_erc1155 MmResult, UpdateNftError> { - let nft_list = get_moralis_nft_list(ctx, chain, url, url_antispam).await?; + let nft_list = get_moralis_nft_list(ctx, chain, url, url_antispam, signed_message).await?; let last_scanned_block = NftTransferHistoryStorageOps::get_last_block_number(storage, chain) .await? .unwrap_or(0); @@ -1302,8 +1412,9 @@ where async fn update_transfers_with_empty_meta( storage: &T, chain: &Chain, - url: &Url, + original_url: &Url, url_antispam: &Url, + signed_message: &GuiAuthValidation, ) -> MmResult<(), UpdateNftError> where T: NftListStorageOps + NftTransferHistoryStorageOps, @@ -1314,8 +1425,9 @@ where addr_id_pair.token_address.clone(), addr_id_pair.token_id, chain, - url, + original_url, url_antispam, + signed_message, ) .await { @@ -1560,3 +1672,21 @@ fn construct_moralis_uri_for_nft(base_url: &Url, address: &str, chain: &Chain) - .append_pair(MORALIS_FORMAT_QUERY_NAME, MORALIS_FORMAT_QUERY_VALUE); Ok(uri) } + +#[derive(Clone, Serialize)] +struct HttpGetPayload { + uri: Url, + signed_message: GuiAuthValidation, +} + +#[derive(Debug, Display, EnumFromStringify)] +pub(crate) enum HttpGetPayloadErr { + #[from_stringify("serde_json::Error")] + #[display(fmt = "Internal: {}", _0)] + Internal(String), +} + +#[inline(always)] +fn http_get_payload_str(uri: Url, signed_message: GuiAuthValidation) -> MmResult { + Ok(serde_json::to_string(&HttpGetPayload { uri, signed_message })?) +} diff --git a/mm2src/coins/nft/nft_errors.rs b/mm2src/coins/nft/nft_errors.rs index db30c00abc..9afadd1ebf 100644 --- a/mm2src/coins/nft/nft_errors.rs +++ b/mm2src/coins/nft/nft_errors.rs @@ -1,8 +1,10 @@ +use super::HttpGetPayloadErr; use crate::eth::GetEthAddressError; #[cfg(target_arch = "wasm32")] use crate::nft::storage::wasm::WasmNftCacheError; use crate::nft::storage::NftStorageError; -use crate::{CoinFindError, GetMyAddressError, NumConversError, UnexpectedDerivationMethod, WithdrawError}; +use crate::{CoinFindError, GetMyAddressError, MyAddressError, NumConversError, PrivKeyPolicyNotAllowed, + UnexpectedDerivationMethod, WithdrawError}; use common::{HttpStatusCode, ParseRfc3339Err}; #[cfg(not(target_arch = "wasm32"))] use db_common::sqlite::rusqlite::Error as SqlError; @@ -24,6 +26,7 @@ pub enum GetNftInfoError { #[from_stringify("serde_json::Error")] #[display(fmt = "Invalid response: {}", _0)] InvalidResponse(String), + #[from_stringify("HttpGetPayloadErr")] #[display(fmt = "Internal: {}", _0)] Internal(String), GetEthAddressError(GetEthAddressError), @@ -155,7 +158,7 @@ pub enum UpdateNftError { #[from_stringify("LockDBError")] #[display(fmt = "DB error {}", _0)] DbError(String), - #[from_stringify("regex::Error")] + #[from_stringify("regex::Error", "MyAddressError", "HttpGetPayloadErr")] #[display(fmt = "Internal: {}", _0)] Internal(String), GetNftInfoError(GetNftInfoError), @@ -213,6 +216,8 @@ pub enum UpdateNftError { CoinDoesntSupportNft { coin: String, }, + #[display(fmt = "Private key policy is not allowed: {}", _0)] + PrivKeyPolicyNotAllowed(PrivKeyPolicyNotAllowed), } impl From for UpdateNftError { @@ -247,6 +252,10 @@ impl From for UpdateNftError { } } +impl From for UpdateNftError { + fn from(e: PrivKeyPolicyNotAllowed) -> Self { Self::PrivKeyPolicyNotAllowed(e) } +} + impl HttpStatusCode for UpdateNftError { fn status_code(&self) -> StatusCode { match self { @@ -265,7 +274,8 @@ impl HttpStatusCode for UpdateNftError { | UpdateNftError::SerdeError(_) | UpdateNftError::ProtectFromSpamError(_) | UpdateNftError::NoSuchCoin { .. } - | UpdateNftError::CoinDoesntSupportNft { .. } => StatusCode::INTERNAL_SERVER_ERROR, + | UpdateNftError::CoinDoesntSupportNft { .. } + | UpdateNftError::PrivKeyPolicyNotAllowed(_) => StatusCode::INTERNAL_SERVER_ERROR, } } } diff --git a/mm2src/coins/nft/nft_tests.rs b/mm2src/coins/nft/nft_tests.rs index 99fae76e1b..05f732a9ee 100644 --- a/mm2src/coins/nft/nft_tests.rs +++ b/mm2src/coins/nft/nft_tests.rs @@ -94,7 +94,7 @@ cross_test!(test_moralis_requests, { "{}/{}/nft?chain=POLYGON&format=decimal", MORALIS_API_ENDPOINT_TEST, TEST_WALLET_ADDR_EVM ); - let response_nft_list = send_request_to_uri(uri_nft_list.as_str()).await.unwrap(); + let response_nft_list = send_request_to_uri(uri_nft_list.as_str(), None).await.unwrap(); let nfts_list = response_nft_list["result"].as_array().unwrap(); for nft_json in nfts_list { let nft_moralis: NftFromMoralis = serde_json::from_str(&nft_json.to_string()).unwrap(); @@ -105,7 +105,7 @@ cross_test!(test_moralis_requests, { "{}/{}/nft/transfers?chain=POLYGON&format=decimal", MORALIS_API_ENDPOINT_TEST, TEST_WALLET_ADDR_EVM ); - let response_transfer_history = send_request_to_uri(uri_history.as_str()).await.unwrap(); + let response_transfer_history = send_request_to_uri(uri_history.as_str(), None).await.unwrap(); let mut transfer_list = response_transfer_history["result"].as_array().unwrap().clone(); assert!(!transfer_list.is_empty()); let first_transfer = transfer_list.remove(transfer_list.len() - 1); @@ -119,7 +119,7 @@ cross_test!(test_moralis_requests, { "{}/nft/0xed55e4477b795eaa9bb4bca24df42214e1a05c18/1111777?chain=POLYGON&format=decimal", MORALIS_API_ENDPOINT_TEST ); - let response_meta = send_request_to_uri(uri_meta.as_str()).await.unwrap(); + let response_meta = send_request_to_uri(uri_meta.as_str(), None).await.unwrap(); let nft_moralis: NftFromMoralis = serde_json::from_str(&response_meta.to_string()).unwrap(); assert_eq!(42563567, nft_moralis.block_number.0); }); @@ -155,7 +155,7 @@ cross_test!(test_antispam_scan_endpoints, { cross_test!(test_camo, { let hex_token_uri = hex::encode("https://tikimetadata.s3.amazonaws.com/tiki_box.json"); let uri_decode = format!("{}/url/decode/{}", BLOCKLIST_API_ENDPOINT, hex_token_uri); - let decode_res = send_request_to_uri(&uri_decode).await.unwrap(); + let decode_res = send_request_to_uri(&uri_decode, None).await.unwrap(); let uri_meta: UriMeta = serde_json::from_value(decode_res).unwrap(); assert_eq!( uri_meta.raw_image_url.unwrap(), diff --git a/mm2src/coins_activation/src/erc20_token_activation.rs b/mm2src/coins_activation/src/erc20_token_activation.rs index 664f2c22fd..ab9c05c91a 100644 --- a/mm2src/coins_activation/src/erc20_token_activation.rs +++ b/mm2src/coins_activation/src/erc20_token_activation.rs @@ -42,6 +42,7 @@ impl From for EnableTokenError { | EthTokenActivationError::ClientConnectionFailed(e) => EnableTokenError::Transport(e), EthTokenActivationError::InvalidPayload(e) => EnableTokenError::InvalidPayload(e), EthTokenActivationError::UnexpectedDerivationMethod(e) => EnableTokenError::UnexpectedDerivationMethod(e), + EthTokenActivationError::PrivKeyPolicyNotAllowed(e) => EnableTokenError::PrivKeyPolicyNotAllowed(e), } } } diff --git a/mm2src/coins_activation/src/eth_with_token_activation.rs b/mm2src/coins_activation/src/eth_with_token_activation.rs index fb0792704e..3267cd80a9 100644 --- a/mm2src/coins_activation/src/eth_with_token_activation.rs +++ b/mm2src/coins_activation/src/eth_with_token_activation.rs @@ -117,6 +117,7 @@ impl From for InitTokensAsMmCoinsError { EthTokenActivationError::UnexpectedDerivationMethod(e) => { InitTokensAsMmCoinsError::UnexpectedDerivationMethod(e) }, + EthTokenActivationError::PrivKeyPolicyNotAllowed(e) => InitTokensAsMmCoinsError::Internal(e.to_string()), } } } diff --git a/mm2src/coins_activation/src/init_erc20_token_activation.rs b/mm2src/coins_activation/src/init_erc20_token_activation.rs index 5bc4e665ff..de322c9ee5 100644 --- a/mm2src/coins_activation/src/init_erc20_token_activation.rs +++ b/mm2src/coins_activation/src/init_erc20_token_activation.rs @@ -59,9 +59,9 @@ impl From for InitTokenError { impl From for InitErc20Error { fn from(e: EthTokenActivationError) -> Self { match e { - EthTokenActivationError::InternalError(_) | EthTokenActivationError::UnexpectedDerivationMethod(_) => { - InitErc20Error::Internal(e.to_string()) - }, + EthTokenActivationError::InternalError(_) + | EthTokenActivationError::UnexpectedDerivationMethod(_) + | EthTokenActivationError::PrivKeyPolicyNotAllowed(_) => InitErc20Error::Internal(e.to_string()), EthTokenActivationError::ClientConnectionFailed(_) | EthTokenActivationError::CouldNotFetchBalance(_) | EthTokenActivationError::InvalidPayload(_) diff --git a/mm2src/coins_activation/src/token.rs b/mm2src/coins_activation/src/token.rs index d1449dea8d..0493c68fdb 100644 --- a/mm2src/coins_activation/src/token.rs +++ b/mm2src/coins_activation/src/token.rs @@ -4,8 +4,8 @@ use crate::platform_coin_with_tokens::{self, RegisterTokenInfo}; use crate::prelude::*; use async_trait::async_trait; use coins::utxo::rpc_clients::UtxoRpcError; -use coins::{lp_coinfind, lp_coinfind_or_err, BalanceError, CoinProtocol, CoinsContext, MmCoinEnum, RegisterCoinError, - UnexpectedDerivationMethod}; +use coins::{lp_coinfind, lp_coinfind_or_err, BalanceError, CoinProtocol, CoinsContext, MmCoinEnum, + PrivKeyPolicyNotAllowed, RegisterCoinError, UnexpectedDerivationMethod}; use common::{HttpStatusCode, StatusCode}; use derive_more::Display; use mm2_core::mm_ctx::MmArc; @@ -63,6 +63,7 @@ pub enum EnableTokenError { Transport(String), Internal(String), InvalidPayload(String), + PrivKeyPolicyNotAllowed(PrivKeyPolicyNotAllowed), } impl From for EnableTokenError { @@ -170,7 +171,8 @@ impl HttpStatusCode for EnableTokenError { | EnableTokenError::Transport(_) | EnableTokenError::CouldNotFetchBalance(_) | EnableTokenError::InvalidConfig(_) - | EnableTokenError::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR, + | EnableTokenError::Internal(_) + | EnableTokenError::PrivKeyPolicyNotAllowed(_) => StatusCode::INTERNAL_SERVER_ERROR, } } } diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index d1e0daacf5..210dd2d31f 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -854,10 +854,7 @@ fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option global_nft_from_privkey(ctx, sepolia_etomic_maker_nft(), priv_key, nft_type), Some(mm_coin) => match mm_coin { - MmCoinEnum::EthCoin(nft) => { - println!("Found EthCoin {:?}", nft.ticker()); - nft - }, + MmCoinEnum::EthCoin(nft) => nft, _ => panic!("Unexpected coin type found. Expected MmCoinEnum::EthCoin"), }, } @@ -870,11 +867,7 @@ fn send_and_spend_erc721_maker_payment() { let erc721_nft = TestNftType::Erc721 { token_id: 1 }; let maker_global_nft = get_or_create_nft(&MM_CTX, SEPOLIA_MAKER_PRIV, Some(erc721_nft)); - let maker_addr = block_on(maker_global_nft.my_addr()); - println!("maker_addr {:?}\n", maker_addr); let taker_global_nft = get_or_create_nft(&MM_CTX1, SEPOLIA_TAKER_PRIV, None); - let taker_addr = block_on(taker_global_nft.my_addr()); - println!("taker_addr {:?}\n", taker_addr); let maker_address = block_on(maker_global_nft.my_addr()); wait_pending_transactions(maker_address); diff --git a/mm2src/mm2_net/src/native_http.rs b/mm2src/mm2_net/src/native_http.rs index 924b4e8448..50e3ec584d 100644 --- a/mm2src/mm2_net/src/native_http.rs +++ b/mm2src/mm2_net/src/native_http.rs @@ -237,12 +237,17 @@ impl From for SlurpError { /// # Errors /// /// Returns an error if the HTTP status code of the response is not in the 2xx range. -pub async fn send_request_to_uri(uri: &str) -> MmResult { +pub async fn send_request_to_uri(uri: &str, body: Option) -> MmResult { + let request_body = match body { + Some(b) => hyper::Body::from(b), + None => Body::empty(), + }; + let request = http::Request::builder() .method("GET") .uri(uri) .header(ACCEPT, HeaderValue::from_static(APPLICATION_JSON)) - .body(hyper::Body::from(""))?; + .body(request_body)?; let (status, _header, body) = slurp_req_body(request).await?; if !status.is_success() { diff --git a/mm2src/mm2_net/src/wasm/http.rs b/mm2src/mm2_net/src/wasm/http.rs index e836da8c68..25cdb29128 100644 --- a/mm2src/mm2_net/src/wasm/http.rs +++ b/mm2src/mm2_net/src/wasm/http.rs @@ -384,7 +384,7 @@ impl RequestBody { /// # Errors /// /// Returns an error if the HTTP status code of the response is not in the 2xx range. -pub async fn send_request_to_uri(uri: &str) -> MmResult { +pub async fn send_request_to_uri(uri: &str, body: Option) -> MmResult { macro_rules! try_or { ($exp:expr, $errtype:ident) => { match $exp { @@ -394,10 +394,11 @@ pub async fn send_request_to_uri(uri: &str) -> MmResult Date: Thu, 9 May 2024 12:41:12 +0700 Subject: [PATCH 020/233] provide UrlSignWrapper structure --- mm2src/coins/nft.rs | 184 ++++++------------ .../utxo/utxo_builder/utxo_conf_builder.rs | 7 +- mm2src/mm2_net/src/transport.rs | 3 +- 3 files changed, 69 insertions(+), 125 deletions(-) diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index 6ce96276b7..e9dbc9b942 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -255,6 +255,12 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft }, }; + let wrapper = UrlSignWrapper { + orig_url: &req.url, + url_antispam: &req.url_antispam, + signed_message: &signed_message, + }; + let nft_transfers = get_moralis_nft_transfers(&ctx, chain, from_block, &req.url, eth_coin, &signed_message).await?; storage.add_transfers_to_history(*chain, nft_transfers).await?; @@ -263,11 +269,9 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft Ok(Some(block)) => block, Ok(None) => { // if there are no rows in NFT LIST table we can try to get nft list from moralis. - let nft_list = - cache_nfts_from_moralis(&ctx, &storage, chain, &req.url, &req.url_antispam, &signed_message) - .await?; + let nft_list = cache_nfts_from_moralis(&ctx, &storage, chain, &wrapper).await?; update_meta_in_transfers(&storage, chain, nft_list).await?; - update_transfers_with_empty_meta(&storage, chain, &req.url, &req.url_antispam, &signed_message).await?; + update_transfers_with_empty_meta(&storage, chain, &wrapper).await?; update_spam(&storage, *chain, &req.url_antispam).await?; update_phishing(&storage, chain, &req.url_antispam).await?; continue; @@ -275,11 +279,9 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft Err(_) => { // if there is an error, then NFT LIST table doesnt exist, so we need to cache nft list from moralis. NftListStorageOps::init(&storage, chain).await?; - let nft_list = - cache_nfts_from_moralis(&ctx, &storage, chain, &req.url, &req.url_antispam, &signed_message) - .await?; + let nft_list = cache_nfts_from_moralis(&ctx, &storage, chain, &wrapper).await?; update_meta_in_transfers(&storage, chain, nft_list).await?; - update_transfers_with_empty_meta(&storage, chain, &req.url, &req.url_antispam, &signed_message).await?; + update_transfers_with_empty_meta(&storage, chain, &wrapper).await?; update_spam(&storage, *chain, &req.url_antispam).await?; update_phishing(&storage, chain, &req.url_antispam).await?; continue; @@ -300,18 +302,9 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft last_nft_block: nft_block.to_string(), }); } - update_nft_list( - ctx.clone(), - &storage, - chain, - scanned_block + 1, - &req.url, - &req.url_antispam, - &signed_message, - ) - .await?; + update_nft_list(ctx.clone(), &storage, chain, scanned_block + 1, &wrapper).await?; update_nft_global_in_coins_ctx(&ctx, &storage, *chain).await?; - update_transfers_with_empty_meta(&storage, chain, &req.url, &req.url_antispam, &signed_message).await?; + update_transfers_with_empty_meta(&storage, chain, &wrapper).await?; update_spam(&storage, *chain, &req.url_antispam).await?; update_phishing(&storage, chain, &req.url_antispam).await?; } @@ -513,28 +506,26 @@ pub async fn refresh_nft_metadata(ctx: MmArc, req: RefreshMetadataReq) -> MmResu }, }; - let token_address_str = eth_addr_to_hex(&req.token_address); - let mut moralis_meta = match get_moralis_metadata( - token_address_str.clone(), - req.token_id.clone(), - &req.chain, - &req.url, - &req.url_antispam, - &signed_message, - ) - .await - { - Ok(moralis_meta) => moralis_meta, - Err(_) => { - storage - .update_nft_spam_by_token_address(&req.chain, token_address_str.clone(), true) - .await?; - storage - .update_transfer_spam_by_token_address(&req.chain, token_address_str.clone(), true) - .await?; - return Ok(()); - }, + let wrapper = UrlSignWrapper { + orig_url: &req.url, + url_antispam: &req.url_antispam, + signed_message: &signed_message, }; + + let token_address_str = eth_addr_to_hex(&req.token_address); + let mut moralis_meta = + match get_moralis_metadata(token_address_str.clone(), req.token_id.clone(), &req.chain, &wrapper).await { + Ok(moralis_meta) => moralis_meta, + Err(_) => { + storage + .update_nft_spam_by_token_address(&req.chain, token_address_str.clone(), true) + .await?; + storage + .update_transfer_spam_by_token_address(&req.chain, token_address_str.clone(), true) + .await?; + return Ok(()); + }, + }; let mut nft_db = storage .get_nft(&req.chain, token_address_str.clone(), req.token_id.clone()) .await? @@ -665,15 +656,13 @@ where async fn get_moralis_nft_list( ctx: &MmArc, chain: &Chain, - original_url: &Url, - url_antispam: &Url, - signed_message: &GuiAuthValidation, + wrapper: &UrlSignWrapper<'_>, ) -> MmResult, GetNftInfoError> { let mut res_list = Vec::new(); let ticker = chain.to_ticker(); let conf = coin_conf(ctx, ticker); let my_address = get_eth_address(ctx, &conf, ticker, &HDPathAccountToAddressId::default()).await?; - let uri_without_cursor = construct_moralis_uri_for_nft(original_url, &my_address.wallet_address, chain)?; + let uri_without_cursor = construct_moralis_uri_for_nft(wrapper.orig_url, &my_address.wallet_address, chain)?; // The cursor returned in the previous response (used for getting the next page). let mut cursor = String::new(); @@ -683,8 +672,8 @@ async fn get_moralis_nft_list( if !cursor.is_empty() { uri.set_query(Some(&cursor)); } - let payload = http_get_payload_str(uri, signed_message.clone())?; - let response = send_request_to_uri(original_url.as_str(), Some(payload)).await?; + let payload = http_get_payload_str(uri, wrapper.signed_message.clone())?; + let response = send_request_to_uri(wrapper.orig_url.as_str(), Some(payload)).await?; if let Some(nfts_list) = response["result"].as_array() { for nft_json in nfts_list { let nft_moralis = NftFromMoralis::deserialize(nft_json)?; @@ -692,7 +681,7 @@ async fn get_moralis_nft_list( Some(contract_type) => contract_type, None => continue, }; - let mut nft = build_nft_from_moralis(*chain, nft_moralis, contract_type, url_antispam).await; + let mut nft = build_nft_from_moralis(*chain, nft_moralis, contract_type, wrapper.url_antispam).await; protect_from_nft_spam_links(&mut nft, false)?; // collect NFTs from the page res_list.push(nft); @@ -932,11 +921,9 @@ async fn get_moralis_metadata( token_address: String, token_id: BigUint, chain: &Chain, - original_url: &Url, - url_antispam: &Url, - signed_message: &GuiAuthValidation, + wrapper: &UrlSignWrapper<'_>, ) -> MmResult { - let mut uri = original_url.clone(); + let mut uri = wrapper.orig_url.clone(); uri.set_path(MORALIS_API_ENDPOINT); uri.path_segments_mut() .map_to_mm(|_| GetNftInfoError::Internal("Invalid URI".to_string()))? @@ -948,14 +935,14 @@ async fn get_moralis_metadata( .append_pair(MORALIS_FORMAT_QUERY_NAME, MORALIS_FORMAT_QUERY_VALUE); drop_mutability!(uri); - let payload = http_get_payload_str(uri, signed_message.clone())?; - let response = send_request_to_uri(original_url.as_str(), Some(payload)).await?; + let payload = http_get_payload_str(uri, wrapper.signed_message.clone())?; + let response = send_request_to_uri(wrapper.orig_url.as_str(), Some(payload)).await?; let nft_moralis: NftFromMoralis = serde_json::from_str(&response.to_string())?; let contract_type = match nft_moralis.contract_type { Some(contract_type) => contract_type, None => return MmError::err(GetNftInfoError::ContractTypeIsNull), }; - let mut nft_metadata = build_nft_from_moralis(*chain, nft_moralis, contract_type, url_antispam).await; + let mut nft_metadata = build_nft_from_moralis(*chain, nft_moralis, contract_type, wrapper.url_antispam).await; protect_from_nft_spam_links(&mut nft_metadata, false)?; Ok(nft_metadata) } @@ -1056,9 +1043,7 @@ async fn update_nft_list( storage: &T, chain: &Chain, scan_from_block: u64, - original_url: &Url, - url_antispam: &Url, - signed_message: &GuiAuthValidation, + wrapper: &UrlSignWrapper<'_>, ) -> MmResult<(), UpdateNftError> { let transfers = storage.get_transfers_from_block(*chain, scan_from_block).await?; let req = MyAddressReq { @@ -1067,16 +1052,7 @@ async fn update_nft_list( }; let my_address = get_my_address(ctx.clone(), req).await?.wallet_address.to_lowercase(); for transfer in transfers.into_iter() { - handle_nft_transfer( - storage, - chain, - original_url, - url_antispam, - signed_message, - transfer, - &my_address, - ) - .await?; + handle_nft_transfer(storage, chain, wrapper, transfer, &my_address).await?; } Ok(()) } @@ -1084,38 +1060,18 @@ async fn update_nft_list( async fn handle_nft_transfer( storage: &T, chain: &Chain, - original_url: &Url, - url_antispam: &Url, - signed_message: &GuiAuthValidation, + wrapper: &UrlSignWrapper<'_>, transfer: NftTransferHistory, my_address: &str, ) -> MmResult<(), UpdateNftError> { match (transfer.status, transfer.contract_type) { (TransferStatus::Send, ContractType::Erc721) => handle_send_erc721(storage, chain, transfer).await, (TransferStatus::Receive, ContractType::Erc721) => { - handle_receive_erc721( - storage, - chain, - transfer, - original_url, - url_antispam, - signed_message, - my_address, - ) - .await + handle_receive_erc721(storage, chain, transfer, wrapper, my_address).await }, (TransferStatus::Send, ContractType::Erc1155) => handle_send_erc1155(storage, chain, transfer).await, (TransferStatus::Receive, ContractType::Erc1155) => { - handle_receive_erc1155( - storage, - chain, - transfer, - original_url, - url_antispam, - signed_message, - my_address, - ) - .await + handle_receive_erc1155(storage, chain, transfer, wrapper, my_address).await }, } } @@ -1151,9 +1107,7 @@ async fn handle_receive_erc721, my_address: &str, ) -> MmResult<(), UpdateNftError> { let token_address_str = eth_addr_to_hex(&transfer.common.token_address); @@ -1180,9 +1134,7 @@ async fn handle_receive_erc721, my_address: &str, ) -> MmResult<(), UpdateNftError> { let token_address_str = eth_addr_to_hex(&transfer.common.token_address); @@ -1271,18 +1221,12 @@ async fn handle_receive_erc1155 { - let nft = match get_moralis_metadata( - token_address_str.clone(), - transfer.token_id.clone(), - chain, - original_url, - url_antispam, - signed_message, - ) - .await + let nft = match get_moralis_metadata(token_address_str.clone(), transfer.token_id.clone(), chain, wrapper) + .await { Ok(moralis_meta) => { - create_nft_from_moralis_metadata(moralis_meta, &transfer, my_address, chain, url_antispam).await? + create_nft_from_moralis_metadata(moralis_meta, &transfer, my_address, chain, wrapper.url_antispam) + .await? }, Err(_) => { mark_as_spam_and_build_empty_meta(storage, chain, token_address_str, &transfer, my_address).await? @@ -1383,11 +1327,9 @@ async fn cache_nfts_from_moralis, ) -> MmResult, UpdateNftError> { - let nft_list = get_moralis_nft_list(ctx, chain, url, url_antispam, signed_message).await?; + let nft_list = get_moralis_nft_list(ctx, chain, wrapper).await?; let last_scanned_block = NftTransferHistoryStorageOps::get_last_block_number(storage, chain) .await? .unwrap_or(0); @@ -1412,9 +1354,7 @@ where async fn update_transfers_with_empty_meta( storage: &T, chain: &Chain, - original_url: &Url, - url_antispam: &Url, - signed_message: &GuiAuthValidation, + wrapper: &UrlSignWrapper<'_>, ) -> MmResult<(), UpdateNftError> where T: NftListStorageOps + NftTransferHistoryStorageOps, @@ -1425,9 +1365,7 @@ where addr_id_pair.token_address.clone(), addr_id_pair.token_id, chain, - original_url, - url_antispam, - signed_message, + wrapper, ) .await { @@ -1680,7 +1618,7 @@ struct HttpGetPayload { } #[derive(Debug, Display, EnumFromStringify)] -pub(crate) enum HttpGetPayloadErr { +enum HttpGetPayloadErr { #[from_stringify("serde_json::Error")] #[display(fmt = "Internal: {}", _0)] Internal(String), @@ -1690,3 +1628,9 @@ pub(crate) enum HttpGetPayloadErr { fn http_get_payload_str(uri: Url, signed_message: GuiAuthValidation) -> MmResult { Ok(serde_json::to_string(&HttpGetPayload { uri, signed_message })?) } + +struct UrlSignWrapper<'a> { + orig_url: &'a Url, + url_antispam: &'a Url, + signed_message: &'a GuiAuthValidation, +} diff --git a/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs b/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs index befbae70f9..5ae7fcb405 100644 --- a/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs +++ b/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs @@ -210,10 +210,9 @@ impl<'a> UtxoConfBuilder<'a> { fn overwintered(&self) -> bool { self.conf["overwintered"].as_u64().unwrap_or(0) == 1 } fn tx_fee_volatility_percent(&self) -> f64 { - match self.conf["txfee_volatility_percent"].as_f64() { - Some(volatility) => volatility, - None => DEFAULT_DYNAMIC_FEE_VOLATILITY_PERCENT, - } + self.conf["txfee_volatility_percent"] + .as_f64() + .unwrap_or(DEFAULT_DYNAMIC_FEE_VOLATILITY_PERCENT) } fn version_group_id(&self, tx_version: i32, overwintered: bool) -> UtxoConfResult { diff --git a/mm2src/mm2_net/src/transport.rs b/mm2src/mm2_net/src/transport.rs index 3774001b35..ca41b19784 100644 --- a/mm2src/mm2_net/src/transport.rs +++ b/mm2src/mm2_net/src/transport.rs @@ -76,7 +76,8 @@ pub struct GuiAuthValidationGenerator { pub address: String, } -/// gui-auth specific data-type that needed in order to perform gui-auth calls +/// Gui-auth specific data-type that needed in order to perform gui-auth calls. +/// Represents a signed message used for authenticating and validating requests processed by the proxy. #[derive(Clone, Serialize)] pub struct GuiAuthValidation { pub coin_ticker: String, From 2e8c662cecb481e8fa9935c13bbf4b9c2aeaeab8 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 9 May 2024 13:18:08 +0700 Subject: [PATCH 021/233] additionally include chain field into UrlSignWrapper --- mm2src/coins/nft.rs | 123 +++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 70 deletions(-) diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index e9dbc9b942..c25e71adab 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -256,6 +256,7 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft }; let wrapper = UrlSignWrapper { + chain, orig_url: &req.url, url_antispam: &req.url_antispam, signed_message: &signed_message, @@ -269,9 +270,9 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft Ok(Some(block)) => block, Ok(None) => { // if there are no rows in NFT LIST table we can try to get nft list from moralis. - let nft_list = cache_nfts_from_moralis(&ctx, &storage, chain, &wrapper).await?; + let nft_list = cache_nfts_from_moralis(&ctx, &storage, &wrapper).await?; update_meta_in_transfers(&storage, chain, nft_list).await?; - update_transfers_with_empty_meta(&storage, chain, &wrapper).await?; + update_transfers_with_empty_meta(&storage, &wrapper).await?; update_spam(&storage, *chain, &req.url_antispam).await?; update_phishing(&storage, chain, &req.url_antispam).await?; continue; @@ -279,9 +280,9 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft Err(_) => { // if there is an error, then NFT LIST table doesnt exist, so we need to cache nft list from moralis. NftListStorageOps::init(&storage, chain).await?; - let nft_list = cache_nfts_from_moralis(&ctx, &storage, chain, &wrapper).await?; + let nft_list = cache_nfts_from_moralis(&ctx, &storage, &wrapper).await?; update_meta_in_transfers(&storage, chain, nft_list).await?; - update_transfers_with_empty_meta(&storage, chain, &wrapper).await?; + update_transfers_with_empty_meta(&storage, &wrapper).await?; update_spam(&storage, *chain, &req.url_antispam).await?; update_phishing(&storage, chain, &req.url_antispam).await?; continue; @@ -302,9 +303,9 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft last_nft_block: nft_block.to_string(), }); } - update_nft_list(ctx.clone(), &storage, chain, scanned_block + 1, &wrapper).await?; + update_nft_list(ctx.clone(), &storage, scanned_block + 1, &wrapper).await?; update_nft_global_in_coins_ctx(&ctx, &storage, *chain).await?; - update_transfers_with_empty_meta(&storage, chain, &wrapper).await?; + update_transfers_with_empty_meta(&storage, &wrapper).await?; update_spam(&storage, *chain, &req.url_antispam).await?; update_phishing(&storage, chain, &req.url_antispam).await?; } @@ -507,25 +508,25 @@ pub async fn refresh_nft_metadata(ctx: MmArc, req: RefreshMetadataReq) -> MmResu }; let wrapper = UrlSignWrapper { + chain: &req.chain, orig_url: &req.url, url_antispam: &req.url_antispam, signed_message: &signed_message, }; let token_address_str = eth_addr_to_hex(&req.token_address); - let mut moralis_meta = - match get_moralis_metadata(token_address_str.clone(), req.token_id.clone(), &req.chain, &wrapper).await { - Ok(moralis_meta) => moralis_meta, - Err(_) => { - storage - .update_nft_spam_by_token_address(&req.chain, token_address_str.clone(), true) - .await?; - storage - .update_transfer_spam_by_token_address(&req.chain, token_address_str.clone(), true) - .await?; - return Ok(()); - }, - }; + let mut moralis_meta = match get_moralis_metadata(token_address_str.clone(), req.token_id.clone(), &wrapper).await { + Ok(moralis_meta) => moralis_meta, + Err(_) => { + storage + .update_nft_spam_by_token_address(&req.chain, token_address_str.clone(), true) + .await?; + storage + .update_transfer_spam_by_token_address(&req.chain, token_address_str.clone(), true) + .await?; + return Ok(()); + }, + }; let mut nft_db = storage .get_nft(&req.chain, token_address_str.clone(), req.token_id.clone()) .await? @@ -653,12 +654,9 @@ where Ok(()) } -async fn get_moralis_nft_list( - ctx: &MmArc, - chain: &Chain, - wrapper: &UrlSignWrapper<'_>, -) -> MmResult, GetNftInfoError> { +async fn get_moralis_nft_list(ctx: &MmArc, wrapper: &UrlSignWrapper<'_>) -> MmResult, GetNftInfoError> { let mut res_list = Vec::new(); + let chain = wrapper.chain; let ticker = chain.to_ticker(); let conf = coin_conf(ctx, ticker); let my_address = get_eth_address(ctx, &conf, ticker, &HDPathAccountToAddressId::default()).await?; @@ -920,10 +918,10 @@ async fn get_fee_details(eth_coin: &EthCoin, transaction_hash: &str) -> Option, ) -> MmResult { let mut uri = wrapper.orig_url.clone(); + let chain = wrapper.chain; uri.set_path(MORALIS_API_ENDPOINT); uri.path_segments_mut() .map_to_mm(|_| GetNftInfoError::Internal("Invalid URI".to_string()))? @@ -1041,10 +1039,10 @@ fn get_transfer_status(my_wallet: &str, to_address: &str) -> TransferStatus { async fn update_nft_list( ctx: MmArc, storage: &T, - chain: &Chain, scan_from_block: u64, wrapper: &UrlSignWrapper<'_>, ) -> MmResult<(), UpdateNftError> { + let chain = wrapper.chain; let transfers = storage.get_transfers_from_block(*chain, scan_from_block).await?; let req = MyAddressReq { coin: chain.to_ticker().to_string(), @@ -1052,26 +1050,26 @@ async fn update_nft_list( }; let my_address = get_my_address(ctx.clone(), req).await?.wallet_address.to_lowercase(); for transfer in transfers.into_iter() { - handle_nft_transfer(storage, chain, wrapper, transfer, &my_address).await?; + handle_nft_transfer(storage, wrapper, transfer, &my_address).await?; } Ok(()) } async fn handle_nft_transfer( storage: &T, - chain: &Chain, wrapper: &UrlSignWrapper<'_>, transfer: NftTransferHistory, my_address: &str, ) -> MmResult<(), UpdateNftError> { + let chain = wrapper.chain; match (transfer.status, transfer.contract_type) { (TransferStatus::Send, ContractType::Erc721) => handle_send_erc721(storage, chain, transfer).await, (TransferStatus::Receive, ContractType::Erc721) => { - handle_receive_erc721(storage, chain, transfer, wrapper, my_address).await + handle_receive_erc721(storage, transfer, wrapper, my_address).await }, (TransferStatus::Send, ContractType::Erc1155) => handle_send_erc1155(storage, chain, transfer).await, (TransferStatus::Receive, ContractType::Erc1155) => { - handle_receive_erc1155(storage, chain, transfer, wrapper, my_address).await + handle_receive_erc1155(storage, transfer, wrapper, my_address).await }, } } @@ -1105,11 +1103,11 @@ async fn handle_send_erc721 async fn handle_receive_erc721( storage: &T, - chain: &Chain, transfer: NftTransferHistory, wrapper: &UrlSignWrapper<'_>, my_address: &str, ) -> MmResult<(), UpdateNftError> { + let chain = wrapper.chain; let token_address_str = eth_addr_to_hex(&transfer.common.token_address); match storage .get_nft(chain, token_address_str.clone(), transfer.token_id.clone()) @@ -1130,13 +1128,8 @@ async fn handle_receive_erc721 { - let mut nft = match get_moralis_metadata( - token_address_str.clone(), - transfer.token_id.clone(), - chain, - wrapper, - ) - .await + let mut nft = match get_moralis_metadata(token_address_str.clone(), transfer.token_id.clone(), wrapper) + .await { Ok(mut moralis_meta) => { // sometimes moralis updates Get All NFTs (which also affects Get Metadata) later @@ -1196,11 +1189,11 @@ async fn handle_send_erc1155( storage: &T, - chain: &Chain, transfer: NftTransferHistory, wrapper: &UrlSignWrapper<'_>, my_address: &str, ) -> MmResult<(), UpdateNftError> { + let chain = wrapper.chain; let token_address_str = eth_addr_to_hex(&transfer.common.token_address); let mut nft = match storage .get_nft(chain, token_address_str.clone(), transfer.token_id.clone()) @@ -1221,9 +1214,7 @@ async fn handle_receive_erc1155 { - let nft = match get_moralis_metadata(token_address_str.clone(), transfer.token_id.clone(), chain, wrapper) - .await - { + let nft = match get_moralis_metadata(token_address_str.clone(), transfer.token_id.clone(), wrapper).await { Ok(moralis_meta) => { create_nft_from_moralis_metadata(moralis_meta, &transfer, my_address, chain, wrapper.url_antispam) .await? @@ -1326,15 +1317,14 @@ async fn mark_as_spam_and_build_empty_meta( ctx: &MmArc, storage: &T, - chain: &Chain, wrapper: &UrlSignWrapper<'_>, ) -> MmResult, UpdateNftError> { - let nft_list = get_moralis_nft_list(ctx, chain, wrapper).await?; - let last_scanned_block = NftTransferHistoryStorageOps::get_last_block_number(storage, chain) + let nft_list = get_moralis_nft_list(ctx, wrapper).await?; + let last_scanned_block = NftTransferHistoryStorageOps::get_last_block_number(storage, wrapper.chain) .await? .unwrap_or(0); storage - .add_nfts_to_list(*chain, nft_list.clone(), last_scanned_block) + .add_nfts_to_list(*wrapper.chain, nft_list.clone(), last_scanned_block) .await?; Ok(nft_list) } @@ -1351,35 +1341,26 @@ where } /// `update_transfers_with_empty_meta` function updates empty metadata in transfers. -async fn update_transfers_with_empty_meta( - storage: &T, - chain: &Chain, - wrapper: &UrlSignWrapper<'_>, -) -> MmResult<(), UpdateNftError> +async fn update_transfers_with_empty_meta(storage: &T, wrapper: &UrlSignWrapper<'_>) -> MmResult<(), UpdateNftError> where T: NftListStorageOps + NftTransferHistoryStorageOps, { + let chain = wrapper.chain; let token_addr_id = storage.get_transfers_with_empty_meta(*chain).await?; for addr_id_pair in token_addr_id.into_iter() { - let mut nft_meta = match get_moralis_metadata( - addr_id_pair.token_address.clone(), - addr_id_pair.token_id, - chain, - wrapper, - ) - .await - { - Ok(nft_meta) => nft_meta, - Err(_) => { - storage - .update_nft_spam_by_token_address(chain, addr_id_pair.token_address.clone(), true) - .await?; - storage - .update_transfer_spam_by_token_address(chain, addr_id_pair.token_address, true) - .await?; - continue; - }, - }; + let mut nft_meta = + match get_moralis_metadata(addr_id_pair.token_address.clone(), addr_id_pair.token_id, wrapper).await { + Ok(nft_meta) => nft_meta, + Err(_) => { + storage + .update_nft_spam_by_token_address(chain, addr_id_pair.token_address.clone(), true) + .await?; + storage + .update_transfer_spam_by_token_address(chain, addr_id_pair.token_address, true) + .await?; + continue; + }, + }; update_transfer_meta_using_nft(storage, chain, &mut nft_meta).await?; } Ok(()) @@ -1629,7 +1610,9 @@ fn http_get_payload_str(uri: Url, signed_message: GuiAuthValidation) -> MmResult Ok(serde_json::to_string(&HttpGetPayload { uri, signed_message })?) } +/// A wrapper struct for holding the chain identifier, original URL from RPC, anti-spam URL and signed message. struct UrlSignWrapper<'a> { + chain: &'a Chain, orig_url: &'a Url, url_antispam: &'a Url, signed_message: &'a GuiAuthValidation, From 0fbf75dd7ca1a9ace3cbe9679723a0ae39b518f5 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 9 May 2024 14:10:04 +0700 Subject: [PATCH 022/233] increase erc721 tx confirmation time to 150, add more logs --- mm2src/coins/nft.rs | 2 +- .../tests/docker_tests/eth_docker_tests.rs | 30 +++++++++++++++---- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index c25e71adab..6c622abff0 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -1610,7 +1610,7 @@ fn http_get_payload_str(uri: Url, signed_message: GuiAuthValidation) -> MmResult Ok(serde_json::to_string(&HttpGetPayload { uri, signed_message })?) } -/// A wrapper struct for holding the chain identifier, original URL from RPC, anti-spam URL and signed message. +/// A wrapper struct for holding the chain identifier, original URL field from RPC, anti-spam URL and signed message. struct UrlSignWrapper<'a> { chain: &'a Chain, orig_url: &'a Url, diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 210dd2d31f..775400e8ff 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -897,16 +897,15 @@ fn send_and_spend_erc721_maker_payment() { }; let maker_payment = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); log!( - "Maker sent ERC721 NFT Payment tx hash {:02x}\n", + "Maker sent ERC721 NFT payment, tx hash: {:02x}", maker_payment.tx_hash() ); - log!("Maker ERC721 NFT Payment transaction\n{:?}", maker_payment); let confirm_input = ConfirmPaymentInput { payment_tx: maker_payment.tx_hex(), confirmations: 1, requires_nota: false, - wait_until: now_sec() + 70, + wait_until: now_sec() + 150, check_every: 1, }; maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); @@ -936,12 +935,16 @@ fn send_and_spend_erc721_maker_payment() { swap_contract_address: &sepolia_etomic_maker_nft(), }; let spend_tx = block_on(taker_global_nft.spend_nft_maker_payment_v2(spend_payment_args)).unwrap(); + log!( + "Taker spent ERC721 NFT Maker payment, tx hash: {:02x}", + spend_tx.tx_hash() + ); let confirm_input = ConfirmPaymentInput { payment_tx: spend_tx.tx_hex(), confirmations: 1, requires_nota: false, - wait_until: now_sec() + 70, + wait_until: now_sec() + 150, check_every: 1, }; taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); @@ -959,11 +962,15 @@ fn send_and_spend_erc721_maker_payment() { erc721_nft, ) .unwrap(); + log!( + "Taker sent ERC721 NFT back to Maker, tx hash: {:02x}", + send_back_tx.tx_hash() + ); let confirm_input = ConfirmPaymentInput { payment_tx: send_back_tx.tx_hex(), confirmations: 1, requires_nota: false, - wait_until: now_sec() + 70, + wait_until: now_sec() + 150, check_every: 1, }; taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); @@ -1005,7 +1012,10 @@ fn send_and_spend_erc1155_maker_payment() { nft_swap_info: &nft_swap_info, }; let maker_payment = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); - log!("Maker sent ERC1155 NFT Payment tx hash {:02x}", maker_payment.tx_hash()); + log!( + "Maker sent ERC1155 NFT payment, tx hash: {:02x}", + maker_payment.tx_hash() + ); let confirm_input = ConfirmPaymentInput { payment_tx: maker_payment.tx_hex(), @@ -1041,6 +1051,10 @@ fn send_and_spend_erc1155_maker_payment() { swap_contract_address: &sepolia_etomic_maker_nft(), }; let spend_tx = block_on(taker_global_nft.spend_nft_maker_payment_v2(spend_payment_args)).unwrap(); + log!( + "Taker spent ERC1155 NFT Maker payment, tx hash: {:02x}", + spend_tx.tx_hash() + ); let confirm_input = ConfirmPaymentInput { payment_tx: spend_tx.tx_hex(), @@ -1065,6 +1079,10 @@ fn send_and_spend_erc1155_maker_payment() { erc1155_nft, ) .unwrap(); + log!( + "Taker sent ERC1155 NFT back to Maker, tx hash: {:02x}", + send_back_tx.tx_hash() + ); let confirm_input = ConfirmPaymentInput { payment_tx: send_back_tx.tx_hex(), confirmations: 1, From 03860e100be3b7fb134537f2e6b74cb8891878b2 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 10 May 2024 15:09:31 +0700 Subject: [PATCH 023/233] review: use map_err for generate_gui_auth_signed_validation, doc comm for MM_CTX1, remove unnecessary Geth args, simplify request_body creation, change sleep duration in tests --- mm2src/coins/eth/v2_activation.rs | 12 ++---- mm2src/coins/eth/web3_transport/mod.rs | 22 +++-------- mm2src/coins/nft.rs | 37 ++++++------------- .../tests/docker_tests/docker_tests_common.rs | 13 +++---- .../tests/docker_tests/eth_docker_tests.rs | 4 +- mm2src/mm2_main/tests/docker_tests_main.rs | 4 +- mm2src/mm2_net/src/native_http.rs | 8 +--- 7 files changed, 31 insertions(+), 69 deletions(-) diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index b1de7fe1bd..1506f1dfbd 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -459,15 +459,9 @@ impl EthCoin { secret, address: my_address_str, }; - let signed_message = match EthCoin::generate_gui_auth_signed_validation(validation_generator) { - Ok(t) => t, - Err(e) => { - return MmError::err(EthTokenActivationError::InternalError(format!( - "GuiAuth signed message generation failed. Error: {:?}", - e - ))) - }, - }; + let signed_message = EthCoin::generate_gui_auth_signed_validation(validation_generator).map_err(|e| { + EthTokenActivationError::InternalError(format!("GuiAuth signed message generation failed. Error: {:?}", e)) + })?; let nft_infos = get_nfts_for_activation(&chain, &my_address, original_url, &signed_message).await?; let global_nft = EthCoinImpl { diff --git a/mm2src/coins/eth/web3_transport/mod.rs b/mm2src/coins/eth/web3_transport/mod.rs index 30cb8b8dcb..087280aa5c 100644 --- a/mm2src/coins/eth/web3_transport/mod.rs +++ b/mm2src/coins/eth/web3_transport/mod.rs @@ -135,24 +135,12 @@ pub(super) fn handle_gui_auth_payload( gui_auth_validation_generator: &Option, request: &Call, ) -> Result { - let generator = match gui_auth_validation_generator.clone() { - Some(gen) => gen, - None => { - return Err(Web3RpcError::Internal( - "GuiAuthValidationGenerator is not provided for".to_string(), - )); - }, - }; + let generator = gui_auth_validation_generator + .clone() + .ok_or_else(|| Web3RpcError::Internal("GuiAuthValidationGenerator is not provided for".to_string()))?; - let signed_message = match EthCoin::generate_gui_auth_signed_validation(generator) { - Ok(t) => t, - Err(e) => { - return Err(Web3RpcError::Internal(format!( - "GuiAuth signed message generation failed. Error: {:?}", - e - ))); - }, - }; + let signed_message = EthCoin::generate_gui_auth_signed_validation(generator) + .map_err(|e| Web3RpcError::Internal(format!("GuiAuth signed message generation failed. Error: {:?}", e)))?; let auth_request = AuthPayload { request, diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index 6c622abff0..53b87d2336 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -245,15 +245,9 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft secret, address: my_address, }; - let signed_message = match EthCoin::generate_gui_auth_signed_validation(validation_generator) { - Ok(t) => t, - Err(e) => { - return MmError::err(UpdateNftError::Internal(format!( - "GuiAuth signed message generation failed. Error: {:?}", - e - ))) - }, - }; + let signed_message = EthCoin::generate_gui_auth_signed_validation(validation_generator).map_err(|e| { + UpdateNftError::Internal(format!("GuiAuth signed message generation failed. Error: {:?}", e)) + })?; let wrapper = UrlSignWrapper { chain, @@ -262,8 +256,7 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft signed_message: &signed_message, }; - let nft_transfers = - get_moralis_nft_transfers(&ctx, chain, from_block, &req.url, eth_coin, &signed_message).await?; + let nft_transfers = get_moralis_nft_transfers(&ctx, from_block, eth_coin, &wrapper).await?; storage.add_transfers_to_history(*chain, nft_transfers).await?; let nft_block = match NftListStorageOps::get_last_block_number(&storage, chain).await { @@ -497,15 +490,8 @@ pub async fn refresh_nft_metadata(ctx: MmArc, req: RefreshMetadataReq) -> MmResu secret, address: my_address, }; - let signed_message = match EthCoin::generate_gui_auth_signed_validation(validation_generator) { - Ok(t) => t, - Err(e) => { - return MmError::err(UpdateNftError::Internal(format!( - "GuiAuth signed message generation failed. Error: {:?}", - e - ))) - }, - }; + let signed_message = EthCoin::generate_gui_auth_signed_validation(validation_generator) + .map_err(|e| UpdateNftError::Internal(format!("GuiAuth signed message generation failed. Error: {:?}", e)))?; let wrapper = UrlSignWrapper { chain: &req.chain, @@ -762,18 +748,17 @@ fn process_nft_list_for_activation( async fn get_moralis_nft_transfers( ctx: &MmArc, - chain: &Chain, from_block: Option, - original_url: &Url, eth_coin: EthCoin, - signed_message: &GuiAuthValidation, + wrapper: &UrlSignWrapper<'_>, ) -> MmResult, GetNftInfoError> { + let chain = wrapper.chain; let mut res_list = Vec::new(); let ticker = chain.to_ticker(); let conf = coin_conf(ctx, ticker); let my_address = get_eth_address(ctx, &conf, ticker, &HDPathAccountToAddressId::default()).await?; - let mut uri_without_cursor = original_url.clone(); + let mut uri_without_cursor = wrapper.orig_url.clone(); uri_without_cursor.set_path(MORALIS_API_ENDPOINT); uri_without_cursor .path_segments_mut() @@ -801,8 +786,8 @@ async fn get_moralis_nft_transfers( if !cursor.is_empty() { uri.set_query(Some(&cursor)); } - let payload = http_get_payload_str(uri, signed_message.clone())?; - let response = send_request_to_uri(original_url.as_str(), Some(payload)).await?; + let payload = http_get_payload_str(uri, wrapper.signed_message.clone())?; + let response = send_request_to_uri(wrapper.orig_url.as_str(), Some(payload)).await?; if let Some(transfer_list) = response["result"].as_array() { process_transfer_list(transfer_list, chain, wallet_address.as_str(), ð_coin, &mut res_list).await?; // if the cursor is not null, there are other NFTs transfers on next page, diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index a9f0e97eb7..644be5101d 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -67,6 +67,11 @@ lazy_static! { // Supply more privkeys when 18 will be not enough. pub static ref SLP_TOKEN_OWNERS: Mutex> = Mutex::new(Vec::with_capacity(18)); pub static ref MM_CTX: MmArc = MmCtxBuilder::new().into_mm_arc(); + /// We need a second `MmCtx` instance when we use the same private keys for Maker and Taker across various tests. + /// When enabling coins for both Maker and Taker, two distinct coin instances are created. + /// This means that different instances of the same coin should have separate global nonce locks. + /// Utilizing different `MmCtx` instances allows us to assign Maker and Taker coins to separate `CoinsCtx`. + /// This approach addresses the `replacement transaction` issue, which occurs when different transactions share the same nonce. pub static ref MM_CTX1: MmArc = MmCtxBuilder::new().into_mm_arc(); pub static ref GETH_WEB3: Web3 = Web3::new(Http::new(GETH_RPC_URL).unwrap()); pub static ref SEPOLIA_WEB3: Web3 = Web3::new(Http::new(SEPOLIA_RPC_URL).unwrap()); @@ -354,13 +359,7 @@ pub fn utxo_asset_docker_node<'a>(docker: &'a Cli, ticker: &'static str, port: u pub fn geth_docker_node<'a>(docker: &'a Cli, ticker: &'static str, port: u16) -> DockerNode<'a> { let image = GenericImage::new(GETH_DOCKER_IMAGE, "stable"); - let args = vec![ - "--dev".into(), - "--http".into(), - "--http.addr=0.0.0.0".into(), - "--dev.period=0".into(), - "--verbosity=4".into(), - ]; + let args = vec!["--dev".into(), "--http".into(), "--http.addr=0.0.0.0".into()]; let image = RunnableImage::from((image, args)).with_mapped_port((port, port)); let container = docker.run(image); DockerNode { diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 775400e8ff..9cffffddca 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -333,7 +333,7 @@ pub fn erc20_coin_with_random_privkey(swap_contract_address: Address) -> EthCoin erc20_coin } -#[derive(Copy, Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub enum TestNftType { Erc1155 { token_id: u32, amount: u32 }, Erc721 { token_id: u32 }, @@ -845,7 +845,7 @@ fn wait_pending_transactions(wallet_address: Address) { "Waiting for pending transactions to confirm... Current nonce: {}, Pending nonce: {}", latest_nonce, pending_nonce ); - thread::sleep(Duration::from_secs(5)); + thread::sleep(Duration::from_secs(1)); } } } diff --git a/mm2src/mm2_main/tests/docker_tests_main.rs b/mm2src/mm2_main/tests/docker_tests_main.rs index 233e5cf88d..2a3377f11a 100644 --- a/mm2src/mm2_main/tests/docker_tests_main.rs +++ b/mm2src/mm2_main/tests/docker_tests_main.rs @@ -105,7 +105,7 @@ pub fn docker_tests_runner(tests: &[&TestDescAndFn]) { fn wait_for_geth_node_ready() { let mut attempts = 0; loop { - if attempts >= 5 { + if attempts >= 10 { println!("Failed to connect to Geth node after several attempts."); break; } @@ -117,7 +117,7 @@ fn wait_for_geth_node_ready() { Err(e) => { println!("Failed to connect to Geth node: {:?}, retrying...", e); attempts += 1; - thread::sleep(Duration::from_secs(5)); + thread::sleep(Duration::from_secs(1)); }, } } diff --git a/mm2src/mm2_net/src/native_http.rs b/mm2src/mm2_net/src/native_http.rs index 50e3ec584d..ea863b0865 100644 --- a/mm2src/mm2_net/src/native_http.rs +++ b/mm2src/mm2_net/src/native_http.rs @@ -13,7 +13,6 @@ use async_trait::async_trait; use futures::channel::oneshot::Canceled; -use http::header::ACCEPT; use http::{header, HeaderValue, Request}; use hyper::client::connect::Connect; use hyper::client::ResponseFuture; @@ -238,15 +237,12 @@ impl From for SlurpError { /// /// Returns an error if the HTTP status code of the response is not in the 2xx range. pub async fn send_request_to_uri(uri: &str, body: Option) -> MmResult { - let request_body = match body { - Some(b) => hyper::Body::from(b), - None => Body::empty(), - }; + let request_body = body.map_or_else(Body::empty, Body::from); let request = http::Request::builder() .method("GET") .uri(uri) - .header(ACCEPT, HeaderValue::from_static(APPLICATION_JSON)) + .header(header::ACCEPT, HeaderValue::from_static(APPLICATION_JSON)) .body(request_body)?; let (status, _header, body) = slurp_req_body(request).await?; From b8b05d1b33d499e062446958e3a4191e86055d47 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 12 May 2024 16:52:00 +0700 Subject: [PATCH 024/233] proxy: send regular http post request to proxy for nft feature --- mm2src/coins/nft.rs | 14 +++++++++----- mm2src/coins/nft/nft_tests.rs | 8 ++++---- mm2src/mm2_net/src/native_http.rs | 6 ++---- mm2src/mm2_net/src/wasm/http.rs | 11 +++++------ 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index 53b87d2336..85ccc9b69e 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -657,7 +657,8 @@ async fn get_moralis_nft_list(ctx: &MmArc, wrapper: &UrlSignWrapper<'_>) -> MmRe uri.set_query(Some(&cursor)); } let payload = http_get_payload_str(uri, wrapper.signed_message.clone())?; - let response = send_request_to_uri(wrapper.orig_url.as_str(), Some(payload)).await?; + let response = send_post_request_to_uri(wrapper.orig_url.as_str(), payload).await?; + let response: Json = serde_json::from_slice(&response)?; if let Some(nfts_list) = response["result"].as_array() { for nft_json in nfts_list { let nft_moralis = NftFromMoralis::deserialize(nft_json)?; @@ -703,7 +704,8 @@ pub(crate) async fn get_nfts_for_activation( uri.set_query(Some(&cursor)); } let payload = http_get_payload_str(uri, signed_message.clone())?; - let response = send_request_to_uri(original_url.as_str(), Some(payload)).await?; + let response = send_post_request_to_uri(original_url.as_str(), payload).await?; + let response: Json = serde_json::from_slice(&response)?; if let Some(nfts_list) = response["result"].as_array() { process_nft_list_for_activation(nfts_list, chain, &mut nfts_map)?; // if cursor is not null, there are other NFTs on next page, @@ -787,7 +789,8 @@ async fn get_moralis_nft_transfers( uri.set_query(Some(&cursor)); } let payload = http_get_payload_str(uri, wrapper.signed_message.clone())?; - let response = send_request_to_uri(wrapper.orig_url.as_str(), Some(payload)).await?; + let response = send_post_request_to_uri(wrapper.orig_url.as_str(), payload).await?; + let response: Json = serde_json::from_slice(&response)?; if let Some(transfer_list) = response["result"].as_array() { process_transfer_list(transfer_list, chain, wallet_address.as_str(), ð_coin, &mut res_list).await?; // if the cursor is not null, there are other NFTs transfers on next page, @@ -919,7 +922,8 @@ async fn get_moralis_metadata( drop_mutability!(uri); let payload = http_get_payload_str(uri, wrapper.signed_message.clone())?; - let response = send_request_to_uri(wrapper.orig_url.as_str(), Some(payload)).await?; + let response = send_post_request_to_uri(wrapper.orig_url.as_str(), payload).await?; + let response: Json = serde_json::from_slice(&response)?; let nft_moralis: NftFromMoralis = serde_json::from_str(&response.to_string())?; let contract_type = match nft_moralis.contract_type { Some(contract_type) => contract_type, @@ -997,7 +1001,7 @@ fn construct_camo_url_with_token(token_uri: &str, url_antispam: &Url) -> Option< } async fn fetch_meta_from_url(url: Url) -> MmResult { - let response_meta = send_request_to_uri(url.as_str(), None).await?; + let response_meta = send_request_to_uri(url.as_str()).await?; serde_json::from_value(response_meta).map_err(|e| e.into()) } diff --git a/mm2src/coins/nft/nft_tests.rs b/mm2src/coins/nft/nft_tests.rs index 05f732a9ee..99fae76e1b 100644 --- a/mm2src/coins/nft/nft_tests.rs +++ b/mm2src/coins/nft/nft_tests.rs @@ -94,7 +94,7 @@ cross_test!(test_moralis_requests, { "{}/{}/nft?chain=POLYGON&format=decimal", MORALIS_API_ENDPOINT_TEST, TEST_WALLET_ADDR_EVM ); - let response_nft_list = send_request_to_uri(uri_nft_list.as_str(), None).await.unwrap(); + let response_nft_list = send_request_to_uri(uri_nft_list.as_str()).await.unwrap(); let nfts_list = response_nft_list["result"].as_array().unwrap(); for nft_json in nfts_list { let nft_moralis: NftFromMoralis = serde_json::from_str(&nft_json.to_string()).unwrap(); @@ -105,7 +105,7 @@ cross_test!(test_moralis_requests, { "{}/{}/nft/transfers?chain=POLYGON&format=decimal", MORALIS_API_ENDPOINT_TEST, TEST_WALLET_ADDR_EVM ); - let response_transfer_history = send_request_to_uri(uri_history.as_str(), None).await.unwrap(); + let response_transfer_history = send_request_to_uri(uri_history.as_str()).await.unwrap(); let mut transfer_list = response_transfer_history["result"].as_array().unwrap().clone(); assert!(!transfer_list.is_empty()); let first_transfer = transfer_list.remove(transfer_list.len() - 1); @@ -119,7 +119,7 @@ cross_test!(test_moralis_requests, { "{}/nft/0xed55e4477b795eaa9bb4bca24df42214e1a05c18/1111777?chain=POLYGON&format=decimal", MORALIS_API_ENDPOINT_TEST ); - let response_meta = send_request_to_uri(uri_meta.as_str(), None).await.unwrap(); + let response_meta = send_request_to_uri(uri_meta.as_str()).await.unwrap(); let nft_moralis: NftFromMoralis = serde_json::from_str(&response_meta.to_string()).unwrap(); assert_eq!(42563567, nft_moralis.block_number.0); }); @@ -155,7 +155,7 @@ cross_test!(test_antispam_scan_endpoints, { cross_test!(test_camo, { let hex_token_uri = hex::encode("https://tikimetadata.s3.amazonaws.com/tiki_box.json"); let uri_decode = format!("{}/url/decode/{}", BLOCKLIST_API_ENDPOINT, hex_token_uri); - let decode_res = send_request_to_uri(&uri_decode, None).await.unwrap(); + let decode_res = send_request_to_uri(&uri_decode).await.unwrap(); let uri_meta: UriMeta = serde_json::from_value(decode_res).unwrap(); assert_eq!( uri_meta.raw_image_url.unwrap(), diff --git a/mm2src/mm2_net/src/native_http.rs b/mm2src/mm2_net/src/native_http.rs index ea863b0865..3f3e9bdec6 100644 --- a/mm2src/mm2_net/src/native_http.rs +++ b/mm2src/mm2_net/src/native_http.rs @@ -236,14 +236,12 @@ impl From for SlurpError { /// # Errors /// /// Returns an error if the HTTP status code of the response is not in the 2xx range. -pub async fn send_request_to_uri(uri: &str, body: Option) -> MmResult { - let request_body = body.map_or_else(Body::empty, Body::from); - +pub async fn send_request_to_uri(uri: &str) -> MmResult { let request = http::Request::builder() .method("GET") .uri(uri) .header(header::ACCEPT, HeaderValue::from_static(APPLICATION_JSON)) - .body(request_body)?; + .body(Body::empty())?; let (status, _header, body) = slurp_req_body(request).await?; if !status.is_success() { diff --git a/mm2src/mm2_net/src/wasm/http.rs b/mm2src/mm2_net/src/wasm/http.rs index 25cdb29128..e836da8c68 100644 --- a/mm2src/mm2_net/src/wasm/http.rs +++ b/mm2src/mm2_net/src/wasm/http.rs @@ -384,7 +384,7 @@ impl RequestBody { /// # Errors /// /// Returns an error if the HTTP status code of the response is not in the 2xx range. -pub async fn send_request_to_uri(uri: &str, body: Option) -> MmResult { +pub async fn send_request_to_uri(uri: &str) -> MmResult { macro_rules! try_or { ($exp:expr, $errtype:ident) => { match $exp { @@ -394,11 +394,10 @@ pub async fn send_request_to_uri(uri: &str, body: Option) -> MmResult Date: Sun, 12 May 2024 19:14:49 +0700 Subject: [PATCH 025/233] make erc721 and erc1155 time locks different in tests --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 9cffffddca..2069f79b04 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -872,7 +872,7 @@ fn send_and_spend_erc721_maker_payment() { let maker_address = block_on(maker_global_nft.my_addr()); wait_pending_transactions(maker_address); - let time_lock = now_sec() + 1000; + let time_lock = now_sec() + 1001; let maker_pubkey = maker_global_nft.derive_htlc_pubkey(&[]); let taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); From 350abd681208c9bccfec5a03a8b93ba19af694d6 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 14 May 2024 18:51:30 +0700 Subject: [PATCH 026/233] review: impl lock_coins() to keep coins field in CoinsContext private --- mm2src/coins/lp_coins.rs | 7 +++++-- mm2src/coins/nft.rs | 2 +- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index a236d2ebb2..de80f843bb 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -56,7 +56,7 @@ use derive_more::Display; use enum_derives::{EnumFromStringify, EnumFromTrait}; use ethereum_types::H256; use futures::compat::Future01CompatExt; -use futures::lock::Mutex as AsyncMutex; +use futures::lock::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard}; use futures::{FutureExt, TryFutureExt}; use futures01::Future; use hex::FromHexError; @@ -3550,7 +3550,7 @@ impl DexFee { pub struct CoinsContext { /// A map from a currency ticker symbol to the corresponding coin. /// Similar to `LP_coins`. - pub coins: AsyncMutex>, + coins: AsyncMutex>, balance_update_handlers: AsyncMutex>>, account_balance_task_manager: AccountBalanceTaskManagerShared, create_account_manager: CreateAccountTaskManagerShared, @@ -3720,6 +3720,9 @@ impl CoinsContext { async fn tx_history_db(&self) -> TxHistoryResult> { Ok(self.tx_history_db.get_or_initialize().await?) } + + #[inline(always)] + pub async fn lock_coins(&self) -> AsyncMutexGuard> { self.coins.lock().await } } /// This enum is used in coin activation requests. diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index 85ccc9b69e..2b82b37e04 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -314,7 +314,7 @@ where T: NftListStorageOps + NftTransferHistoryStorageOps, { let coins_ctx = CoinsContext::from_ctx(ctx).map_to_mm(UpdateNftError::Internal)?; - let mut coins = coins_ctx.coins.lock().await; + let mut coins = coins_ctx.lock_coins().await; let ticker = chain.to_nft_ticker(); if let Some(MmCoinStruct { diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 2069f79b04..ff2a570018 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -411,7 +411,7 @@ fn global_nft_from_privkey( .unwrap(); let coins_ctx = CoinsContext::from_ctx(ctx).unwrap(); - let mut coins = block_on(coins_ctx.coins.lock()); + let mut coins = block_on(coins_ctx.lock_coins()); coins.insert( global_nft.ticker().into(), MmCoinStruct::new(MmCoinEnum::EthCoin(global_nft.clone())), From 36eaf389f1604136efefc3c4aabb159728dee1ac Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 15 May 2024 10:58:25 +0700 Subject: [PATCH 027/233] review: rename Gui-Auth types to align with new names in the KomodoDefi Proxy project --- mm2src/coins/eth.rs | 33 +++++++------- mm2src/coins/eth/v2_activation.rs | 15 ++++--- .../eth/web3_transport/http_transport.rs | 18 ++++---- mm2src/coins/eth/web3_transport/mod.rs | 30 +++++++------ .../eth/web3_transport/websocket_transport.rs | 10 ++--- mm2src/coins/nft.rs | 45 +++++++++++-------- mm2src/coins/nft/nft_errors.rs | 6 +-- mm2src/mm2_net/src/transport.rs | 6 +-- 8 files changed, 89 insertions(+), 74 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 9f688427bf..e46073f569 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -76,7 +76,7 @@ use instant::Instant; use keys::Public as HtlcPubKey; use mm2_core::mm_ctx::{MmArc, MmWeak}; use mm2_event_stream::behaviour::{EventBehaviour, EventInitStatus}; -use mm2_net::transport::{slurp_url, GuiAuthValidation, GuiAuthValidationGenerator, SlurpError}; +use mm2_net::transport::{slurp_url, KomodefiProxyAuthValidation, ProxyAuthValidationGenerator, SlurpError}; use mm2_number::bigdecimal_custom::CheckedDivision; use mm2_number::{BigDecimal, BigUint, MmNumber}; use mm2_rpc::data::legacy::GasStationPricePolicy; @@ -199,8 +199,8 @@ const GAS_PRICE_APPROXIMATION_PERCENT_ON_TRADE_PREIMAGE: u64 = 7; pub const ETH_GAS: u64 = 150_000; -/// Lifetime of generated signed message for gui-auth requests -const GUI_AUTH_SIGNED_MESSAGE_LIFETIME_SEC: i64 = 90; +/// Lifetime of generated signed message for proxy-auth requests +const PROXY_AUTH_SIGNED_MESSAGE_LIFETIME_SEC: i64 = 90; lazy_static! { pub static ref SWAP_CONTRACT: Contract = Contract::load(SWAP_CONTRACT_ABI.as_bytes()).unwrap(); @@ -5428,14 +5428,15 @@ impl TryToAddress for Option { } } -pub trait GuiAuthMessages { - fn gui_auth_sign_message_hash(message: String) -> Option<[u8; 32]>; - fn generate_gui_auth_signed_validation(generator: GuiAuthValidationGenerator) - -> SignatureResult; +pub trait KomodoDefiAuthMessages { + fn proxy_auth_sign_message_hash(message: String) -> Option<[u8; 32]>; + fn generate_proxy_auth_signed_validation( + generator: ProxyAuthValidationGenerator, + ) -> SignatureResult; } -impl GuiAuthMessages for EthCoin { - fn gui_auth_sign_message_hash(message: String) -> Option<[u8; 32]> { +impl KomodoDefiAuthMessages for EthCoin { + fn proxy_auth_sign_message_hash(message: String) -> Option<[u8; 32]> { let message_prefix = "atomicDEX Auth Ethereum Signed Message:\n"; let prefix_len = CompactInteger::from(message_prefix.len()); @@ -5448,16 +5449,16 @@ impl GuiAuthMessages for EthCoin { Some(keccak256(&stream.out()).take()) } - fn generate_gui_auth_signed_validation( - generator: GuiAuthValidationGenerator, - ) -> SignatureResult { - let timestamp_message = get_utc_timestamp() + GUI_AUTH_SIGNED_MESSAGE_LIFETIME_SEC; + fn generate_proxy_auth_signed_validation( + generator: ProxyAuthValidationGenerator, + ) -> SignatureResult { + let timestamp_message = get_utc_timestamp() + PROXY_AUTH_SIGNED_MESSAGE_LIFETIME_SEC; - let message_hash = - EthCoin::gui_auth_sign_message_hash(timestamp_message.to_string()).ok_or(SignatureError::PrefixNotFound)?; + let message_hash = EthCoin::proxy_auth_sign_message_hash(timestamp_message.to_string()) + .ok_or(SignatureError::PrefixNotFound)?; let signature = sign(&generator.secret, &H256::from(message_hash))?; - Ok(GuiAuthValidation { + Ok(KomodefiProxyAuthValidation { coin_ticker: generator.coin_ticker, address: generator.address, timestamp_message, diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 1506f1dfbd..2a9944d9fd 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -376,7 +376,7 @@ impl EthCoin { .iter() .map(|node| { let mut transport = node.web3.transport().clone(); - if let Some(auth) = transport.gui_auth_validation_generator_as_mut() { + if let Some(auth) = transport.proxy_auth_validation_generator_as_mut() { auth.coin_ticker = ticker.clone(); } let web3 = Web3::new(transport); @@ -454,13 +454,16 @@ impl EthCoin { let my_address = self.derivation_method.single_addr_or_err().await?; let my_address_str = display_eth_address(&my_address); let secret = self.priv_key_policy().activated_key_or_err()?.secret().clone(); - let validation_generator = GuiAuthValidationGenerator { + let validation_generator = ProxyAuthValidationGenerator { coin_ticker: chain.to_nft_ticker().to_string(), secret, address: my_address_str, }; - let signed_message = EthCoin::generate_gui_auth_signed_validation(validation_generator).map_err(|e| { - EthTokenActivationError::InternalError(format!("GuiAuth signed message generation failed. Error: {:?}", e)) + let signed_message = EthCoin::generate_proxy_auth_signed_validation(validation_generator).map_err(|e| { + EthTokenActivationError::InternalError(format!( + "KomodefiProxyAuthValidation signed message generation failed. Error: {:?}", + e + )) })?; let nft_infos = get_nfts_for_activation(&chain, &my_address, original_url, &signed_message).await?; @@ -772,7 +775,7 @@ async fn build_web3_instances( let mut websocket_transport = WebsocketTransport::with_event_handlers(node, event_handlers.clone()); if eth_node.gui_auth { - websocket_transport.gui_auth_validation_generator = Some(GuiAuthValidationGenerator { + websocket_transport.proxy_auth_validation_generator = Some(ProxyAuthValidationGenerator { coin_ticker: coin_ticker.clone(), secret: key_pair.secret().clone(), address: address.clone(), @@ -848,7 +851,7 @@ fn build_http_transport( let mut http_transport = HttpTransport::with_event_handlers(node, event_handlers); if gui_auth { - http_transport.gui_auth_validation_generator = Some(GuiAuthValidationGenerator { + http_transport.proxy_auth_validation_generator = Some(ProxyAuthValidationGenerator { coin_ticker, secret: key_pair.secret().clone(), address, diff --git a/mm2src/coins/eth/web3_transport/http_transport.rs b/mm2src/coins/eth/web3_transport/http_transport.rs index e722b16824..463e2455fa 100644 --- a/mm2src/coins/eth/web3_transport/http_transport.rs +++ b/mm2src/coins/eth/web3_transport/http_transport.rs @@ -1,9 +1,9 @@ -use crate::eth::web3_transport::handle_gui_auth_payload; +use crate::eth::web3_transport::handle_quicknode_payload; use crate::eth::{web3_transport::Web3SendOut, RpcTransportEventHandler, RpcTransportEventHandlerShared, Web3RpcError}; use common::APPLICATION_JSON; use http::header::CONTENT_TYPE; use jsonrpc_core::{Call, Response}; -use mm2_net::transport::{GuiAuthValidation, GuiAuthValidationGenerator}; +use mm2_net::transport::{KomodefiProxyAuthValidation, ProxyAuthValidationGenerator}; use serde_json::Value as Json; use std::ops::Deref; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; @@ -13,10 +13,10 @@ use web3::helpers::{build_request, to_result_from_output, to_string}; use web3::{RequestId, Transport}; #[derive(Clone, Serialize)] -pub struct AuthPayload<'a> { +pub struct QuicknodePayload<'a> { #[serde(flatten)] pub request: &'a Call, - pub signed_message: GuiAuthValidation, + pub signed_message: KomodefiProxyAuthValidation, } /// Deserialize bytes RPC response into `Result`. @@ -46,7 +46,7 @@ pub struct HttpTransport { pub(crate) last_request_failed: Arc, node: HttpTransportNode, event_handlers: Vec, - pub(crate) gui_auth_validation_generator: Option, + pub(crate) proxy_auth_validation_generator: Option, } #[derive(Clone, Debug)] @@ -63,7 +63,7 @@ impl HttpTransport { id: Arc::new(AtomicUsize::new(0)), node, event_handlers: Default::default(), - gui_auth_validation_generator: None, + proxy_auth_validation_generator: None, last_request_failed: Arc::new(AtomicBool::new(false)), } } @@ -74,7 +74,7 @@ impl HttpTransport { id: Arc::new(AtomicUsize::new(0)), node, event_handlers, - gui_auth_validation_generator: None, + proxy_auth_validation_generator: None, last_request_failed: Arc::new(AtomicBool::new(false)), } } @@ -111,7 +111,7 @@ async fn send_request(request: Call, transport: HttpTransport) -> Result serialized_request = r, Err(e) => { return Err(request_failed_error(request, e)); @@ -187,7 +187,7 @@ async fn send_request(request: Call, transport: HttpTransport) -> Result serialized_request = r, Err(e) => { return Err(request_failed_error( diff --git a/mm2src/coins/eth/web3_transport/mod.rs b/mm2src/coins/eth/web3_transport/mod.rs index 087280aa5c..e423bca85c 100644 --- a/mm2src/coins/eth/web3_transport/mod.rs +++ b/mm2src/coins/eth/web3_transport/mod.rs @@ -2,15 +2,15 @@ use ethereum_types::U256; use futures::future::BoxFuture; use jsonrpc_core::Call; #[cfg(target_arch = "wasm32")] use mm2_metamask::MetamaskResult; -use mm2_net::transport::GuiAuthValidationGenerator; +use mm2_net::transport::ProxyAuthValidationGenerator; use serde_json::Value as Json; use serde_json::Value; use std::sync::atomic::Ordering; use web3::helpers::to_string; use web3::{Error, RequestId, Transport}; -use self::http_transport::AuthPayload; -use super::{EthCoin, GuiAuthMessages, Web3RpcError}; +use self::http_transport::QuicknodePayload; +use super::{EthCoin, KomodoDefiAuthMessages, Web3RpcError}; use crate::RpcTransportEventHandlerShared; pub(crate) mod http_transport; @@ -67,10 +67,10 @@ impl Web3Transport { http_transport::HttpTransport::new(node).into() } - pub fn gui_auth_validation_generator_as_mut(&mut self) -> Option<&mut GuiAuthValidationGenerator> { + pub fn proxy_auth_validation_generator_as_mut(&mut self) -> Option<&mut ProxyAuthValidationGenerator> { match self { - Web3Transport::Http(http) => http.gui_auth_validation_generator.as_mut(), - Web3Transport::Websocket(websocket) => websocket.gui_auth_validation_generator.as_mut(), + Web3Transport::Http(http) => http.proxy_auth_validation_generator.as_mut(), + Web3Transport::Websocket(websocket) => websocket.proxy_auth_validation_generator.as_mut(), #[cfg(target_arch = "wasm32")] Web3Transport::Metamask(_) => None, } @@ -131,18 +131,22 @@ pub struct FeeHistoryResult { } /// Generates a signed message and inserts it into the request payload. -pub(super) fn handle_gui_auth_payload( - gui_auth_validation_generator: &Option, +pub(super) fn handle_quicknode_payload( + proxy_auth_validation_generator: &Option, request: &Call, ) -> Result { - let generator = gui_auth_validation_generator + let generator = proxy_auth_validation_generator .clone() - .ok_or_else(|| Web3RpcError::Internal("GuiAuthValidationGenerator is not provided for".to_string()))?; + .ok_or_else(|| Web3RpcError::Internal("ProxyAuthValidationGenerator is not provided for".to_string()))?; - let signed_message = EthCoin::generate_gui_auth_signed_validation(generator) - .map_err(|e| Web3RpcError::Internal(format!("GuiAuth signed message generation failed. Error: {:?}", e)))?; + let signed_message = EthCoin::generate_proxy_auth_signed_validation(generator).map_err(|e| { + Web3RpcError::Internal(format!( + "KomodefiProxyAuthValidation signed message generation failed. Error: {:?}", + e + )) + })?; - let auth_request = AuthPayload { + let auth_request = QuicknodePayload { request, signed_message, }; diff --git a/mm2src/coins/eth/web3_transport/websocket_transport.rs b/mm2src/coins/eth/web3_transport/websocket_transport.rs index f458aacc67..951ed4d2c6 100644 --- a/mm2src/coins/eth/web3_transport/websocket_transport.rs +++ b/mm2src/coins/eth/web3_transport/websocket_transport.rs @@ -5,7 +5,7 @@ //! less bandwidth. This efficiency is achieved by avoiding the handling of TCP handshakes (connection reusability) //! for each request. -use super::handle_gui_auth_payload; +use super::handle_quicknode_payload; use super::http_transport::de_rpc_response; use crate::eth::eth_rpc::ETH_RPC_REQUEST_TIMEOUT; use crate::eth::web3_transport::Web3SendOut; @@ -21,7 +21,7 @@ use futures_ticker::Ticker; use futures_util::{FutureExt, SinkExt, StreamExt}; use instant::{Duration, Instant}; use jsonrpc_core::Call; -use mm2_net::transport::GuiAuthValidationGenerator; +use mm2_net::transport::ProxyAuthValidationGenerator; use std::sync::atomic::AtomicBool; use std::sync::{atomic::{AtomicUsize, Ordering}, Arc}; @@ -46,7 +46,7 @@ pub struct WebsocketTransport { pub(crate) last_request_failed: Arc, node: WebsocketTransportNode, event_handlers: Vec, - pub(crate) gui_auth_validation_generator: Option, + pub(crate) proxy_auth_validation_generator: Option, controller_channel: Arc, connection_guard: Arc>, } @@ -93,7 +93,7 @@ impl WebsocketTransport { } .into(), connection_guard: Arc::new(AsyncMutex::new(())), - gui_auth_validation_generator: None, + proxy_auth_validation_generator: None, last_request_failed: Arc::new(AtomicBool::new(false)), } } @@ -343,7 +343,7 @@ async fn send_request( let mut serialized_request = to_string(&request); if transport.node.gui_auth { - match handle_gui_auth_payload(&transport.gui_auth_validation_generator, &request) { + match handle_quicknode_payload(&transport.proxy_auth_validation_generator, &request) { Ok(r) => serialized_request = r, Err(e) => { return Err(Error::Transport(TransportError::Message(format!( diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index 2b82b37e04..ee165cc70a 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -16,7 +16,7 @@ use nft_structs::{Chain, ContractType, ConvertChain, Nft, NftFromMoralis, NftLis TransactionNftDetails, UpdateNftReq, WithdrawNftReq}; use crate::eth::{eth_addr_to_hex, get_eth_address, withdraw_erc1155, withdraw_erc721, EthCoin, EthCoinType, - EthTxFeeDetails, GuiAuthMessages}; + EthTxFeeDetails, KomodoDefiAuthMessages}; use crate::hd_wallet::HDPathAccountToAddressId; use crate::nft::nft_errors::{ClearNftDbError, MetaFromUrlError, ProtectFromSpamError, TransferConfirmationsError, UpdateSpamPhishingError}; @@ -31,7 +31,7 @@ use ethereum_types::{Address, H256}; use futures::compat::Future01CompatExt; use futures::future::try_join_all; use mm2_err_handle::map_to_mm::MapToMmResult; -use mm2_net::transport::{send_post_request_to_uri, GuiAuthValidation, GuiAuthValidationGenerator}; +use mm2_net::transport::{send_post_request_to_uri, KomodefiProxyAuthValidation, ProxyAuthValidationGenerator}; use mm2_number::BigUint; use regex::Regex; use serde::Deserialize; @@ -240,13 +240,16 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft let my_address = eth_coin.my_address()?; let secret = eth_coin.priv_key_policy.activated_key_or_err()?.secret().clone(); - let validation_generator = GuiAuthValidationGenerator { + let validation_generator = ProxyAuthValidationGenerator { coin_ticker: chain.to_nft_ticker().to_string(), secret, address: my_address, }; - let signed_message = EthCoin::generate_gui_auth_signed_validation(validation_generator).map_err(|e| { - UpdateNftError::Internal(format!("GuiAuth signed message generation failed. Error: {:?}", e)) + let signed_message = EthCoin::generate_proxy_auth_signed_validation(validation_generator).map_err(|e| { + UpdateNftError::Internal(format!( + "KomodefiProxyAuthValidation signed message generation failed. Error: {:?}", + e + )) })?; let wrapper = UrlSignWrapper { @@ -485,13 +488,17 @@ pub async fn refresh_nft_metadata(ctx: MmArc, req: RefreshMetadataReq) -> MmResu let my_address = eth_coin.my_address()?; let secret = eth_coin.priv_key_policy.activated_key_or_err()?.secret().clone(); - let validation_generator = GuiAuthValidationGenerator { + let validation_generator = ProxyAuthValidationGenerator { coin_ticker: req.chain.to_nft_ticker().to_string(), secret, address: my_address, }; - let signed_message = EthCoin::generate_gui_auth_signed_validation(validation_generator) - .map_err(|e| UpdateNftError::Internal(format!("GuiAuth signed message generation failed. Error: {:?}", e)))?; + let signed_message = EthCoin::generate_proxy_auth_signed_validation(validation_generator).map_err(|e| { + UpdateNftError::Internal(format!( + "KomodefiProxyAuthValidation signed message generation failed. Error: {:?}", + e + )) + })?; let wrapper = UrlSignWrapper { chain: &req.chain, @@ -656,7 +663,7 @@ async fn get_moralis_nft_list(ctx: &MmArc, wrapper: &UrlSignWrapper<'_>) -> MmRe if !cursor.is_empty() { uri.set_query(Some(&cursor)); } - let payload = http_get_payload_str(uri, wrapper.signed_message.clone())?; + let payload = moralis_payload_str(uri, wrapper.signed_message.clone())?; let response = send_post_request_to_uri(wrapper.orig_url.as_str(), payload).await?; let response: Json = serde_json::from_slice(&response)?; if let Some(nfts_list) = response["result"].as_array() { @@ -690,7 +697,7 @@ pub(crate) async fn get_nfts_for_activation( chain: &Chain, my_address: &Address, original_url: &Url, - signed_message: &GuiAuthValidation, + signed_message: &KomodefiProxyAuthValidation, ) -> MmResult, GetNftInfoError> { let mut nfts_map = HashMap::new(); let uri_without_cursor = construct_moralis_uri_for_nft(original_url, ð_addr_to_hex(my_address), chain)?; @@ -703,7 +710,7 @@ pub(crate) async fn get_nfts_for_activation( if !cursor.is_empty() { uri.set_query(Some(&cursor)); } - let payload = http_get_payload_str(uri, signed_message.clone())?; + let payload = moralis_payload_str(uri, signed_message.clone())?; let response = send_post_request_to_uri(original_url.as_str(), payload).await?; let response: Json = serde_json::from_slice(&response)?; if let Some(nfts_list) = response["result"].as_array() { @@ -788,7 +795,7 @@ async fn get_moralis_nft_transfers( if !cursor.is_empty() { uri.set_query(Some(&cursor)); } - let payload = http_get_payload_str(uri, wrapper.signed_message.clone())?; + let payload = moralis_payload_str(uri, wrapper.signed_message.clone())?; let response = send_post_request_to_uri(wrapper.orig_url.as_str(), payload).await?; let response: Json = serde_json::from_slice(&response)?; if let Some(transfer_list) = response["result"].as_array() { @@ -921,7 +928,7 @@ async fn get_moralis_metadata( .append_pair(MORALIS_FORMAT_QUERY_NAME, MORALIS_FORMAT_QUERY_VALUE); drop_mutability!(uri); - let payload = http_get_payload_str(uri, wrapper.signed_message.clone())?; + let payload = moralis_payload_str(uri, wrapper.signed_message.clone())?; let response = send_post_request_to_uri(wrapper.orig_url.as_str(), payload).await?; let response: Json = serde_json::from_slice(&response)?; let nft_moralis: NftFromMoralis = serde_json::from_str(&response.to_string())?; @@ -1582,21 +1589,21 @@ fn construct_moralis_uri_for_nft(base_url: &Url, address: &str, chain: &Chain) - } #[derive(Clone, Serialize)] -struct HttpGetPayload { +struct MoralisPayload { uri: Url, - signed_message: GuiAuthValidation, + signed_message: KomodefiProxyAuthValidation, } #[derive(Debug, Display, EnumFromStringify)] -enum HttpGetPayloadErr { +enum MoralisPayloadErr { #[from_stringify("serde_json::Error")] #[display(fmt = "Internal: {}", _0)] Internal(String), } #[inline(always)] -fn http_get_payload_str(uri: Url, signed_message: GuiAuthValidation) -> MmResult { - Ok(serde_json::to_string(&HttpGetPayload { uri, signed_message })?) +fn moralis_payload_str(uri: Url, signed_message: KomodefiProxyAuthValidation) -> MmResult { + Ok(serde_json::to_string(&MoralisPayload { uri, signed_message })?) } /// A wrapper struct for holding the chain identifier, original URL field from RPC, anti-spam URL and signed message. @@ -1604,5 +1611,5 @@ struct UrlSignWrapper<'a> { chain: &'a Chain, orig_url: &'a Url, url_antispam: &'a Url, - signed_message: &'a GuiAuthValidation, + signed_message: &'a KomodefiProxyAuthValidation, } diff --git a/mm2src/coins/nft/nft_errors.rs b/mm2src/coins/nft/nft_errors.rs index 9afadd1ebf..3ae031b6f5 100644 --- a/mm2src/coins/nft/nft_errors.rs +++ b/mm2src/coins/nft/nft_errors.rs @@ -1,4 +1,4 @@ -use super::HttpGetPayloadErr; +use super::MoralisPayloadErr; use crate::eth::GetEthAddressError; #[cfg(target_arch = "wasm32")] use crate::nft::storage::wasm::WasmNftCacheError; @@ -26,7 +26,7 @@ pub enum GetNftInfoError { #[from_stringify("serde_json::Error")] #[display(fmt = "Invalid response: {}", _0)] InvalidResponse(String), - #[from_stringify("HttpGetPayloadErr")] + #[from_stringify("MoralisPayloadErr")] #[display(fmt = "Internal: {}", _0)] Internal(String), GetEthAddressError(GetEthAddressError), @@ -158,7 +158,7 @@ pub enum UpdateNftError { #[from_stringify("LockDBError")] #[display(fmt = "DB error {}", _0)] DbError(String), - #[from_stringify("regex::Error", "MyAddressError", "HttpGetPayloadErr")] + #[from_stringify("regex::Error", "MyAddressError", "MoralisPayloadErr")] #[display(fmt = "Internal: {}", _0)] Internal(String), GetNftInfoError(GetNftInfoError), diff --git a/mm2src/mm2_net/src/transport.rs b/mm2src/mm2_net/src/transport.rs index ca41b19784..35bbab434b 100644 --- a/mm2src/mm2_net/src/transport.rs +++ b/mm2src/mm2_net/src/transport.rs @@ -70,16 +70,16 @@ where } #[derive(Clone, Debug)] -pub struct GuiAuthValidationGenerator { +pub struct ProxyAuthValidationGenerator { pub coin_ticker: String, pub secret: Secret, pub address: String, } -/// Gui-auth specific data-type that needed in order to perform gui-auth calls. +/// Proxy-auth specific data-type that needed in order to perform proxy-auth calls. /// Represents a signed message used for authenticating and validating requests processed by the proxy. #[derive(Clone, Serialize)] -pub struct GuiAuthValidation { +pub struct KomodefiProxyAuthValidation { pub coin_ticker: String, pub address: String, pub timestamp_message: i64, From 4478ccb9041a180b3680ae92feda3916fff87769 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 15 May 2024 13:54:45 +0700 Subject: [PATCH 028/233] review: use "http-rustls-tls" feature in web3 crate for tests --- Cargo.lock | 141 +++++-------------------------------- mm2src/mm2_main/Cargo.toml | 2 +- 2 files changed, 20 insertions(+), 123 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd816b513f..94a859920a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -327,7 +327,7 @@ checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", - "bitflags 1.3.2", + "bitflags", "bytes 1.4.0", "futures-util", "http 0.2.12", @@ -544,12 +544,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitflags" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" - [[package]] name = "bitvec" version = "0.18.5" @@ -979,7 +973,7 @@ checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ "ansi_term", "atty", - "bitflags 1.3.2", + "bitflags", "strsim 0.8.0", "textwrap", "unicode-width", @@ -992,7 +986,7 @@ version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "bitflags 1.3.2", + "bitflags", ] [[package]] @@ -1001,7 +995,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" dependencies = [ - "bitflags 1.3.2", + "bitflags", ] [[package]] @@ -2468,21 +2462,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.0.1" @@ -3174,19 +3153,6 @@ dependencies = [ "tokio-io-timeout", ] -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes 1.4.0", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - [[package]] name = "iana-time-zone" version = "0.1.53" @@ -3556,7 +3522,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" dependencies = [ "arrayvec 0.5.1", - "bitflags 1.3.2", + "bitflags", "cfg-if 1.0.0", "ryu", "static_assertions", @@ -4929,24 +4895,6 @@ dependencies = [ "unsigned-varint", ] -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "netlink-packet-core" version = "0.4.2" @@ -4966,7 +4914,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9ea4302b9759a7a88242299225ea3688e63c85ea136371bb6cf94fd674efaab" dependencies = [ "anyhow", - "bitflags 1.3.2", + "bitflags", "byteorder", "libc", "netlink-packet-core", @@ -5028,7 +4976,7 @@ version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cc", "cfg-if 1.0.0", "libc", @@ -5041,7 +4989,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cfg-if 1.0.0", "libc", ] @@ -5179,50 +5127,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -[[package]] -name = "openssl" -version = "0.10.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" -dependencies = [ - "bitflags 2.4.2", - "cfg-if 1.0.0", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 2.0.38", -] - [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-sys" -version = "0.9.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "ordered-float" version = "3.7.0" @@ -5561,7 +5471,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" dependencies = [ "autocfg 1.1.0", - "bitflags 1.3.2", + "bitflags", "cfg-if 1.0.0", "concurrent-queue 2.2.0", "libc", @@ -6132,7 +6042,7 @@ version = "10.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c49596760fce12ca21550ac21dc5a9617b2ea4b6e0aa7d8dab8ff2824fc2bba" dependencies = [ - "bitflags 1.3.2", + "bitflags", ] [[package]] @@ -6193,7 +6103,7 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" dependencies = [ - "bitflags 1.3.2", + "bitflags", ] [[package]] @@ -6270,13 +6180,11 @@ dependencies = [ "http-body 0.4.5", "hyper", "hyper-rustls 0.23.0", - "hyper-tls", "ipnet", "js-sys", "lazy_static", "log", "mime", - "native-tls", "percent-encoding", "pin-project-lite 0.2.9", "rustls 0.20.4", @@ -6285,7 +6193,6 @@ dependencies = [ "serde_json", "serde_urlencoded", "tokio", - "tokio-native-tls", "tokio-rustls 0.23.2", "url", "wasm-bindgen", @@ -6469,7 +6376,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" dependencies = [ - "bitflags 1.3.2", + "bitflags", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -6538,7 +6445,7 @@ version = "0.36.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc" dependencies = [ - "bitflags 1.3.2", + "bitflags", "errno 0.2.8", "io-lifetimes", "libc", @@ -6552,7 +6459,7 @@ version = "0.37.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d" dependencies = [ - "bitflags 1.3.2", + "bitflags", "errno 0.3.1", "io-lifetimes", "libc", @@ -6807,7 +6714,7 @@ version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ - "bitflags 1.3.2", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -7541,7 +7448,7 @@ checksum = "0a463f546a2f5842d35974bd4691ae5ceded6785ec24db440f773723f6ce4e11" dependencies = [ "base64 0.13.0", "bincode", - "bitflags 1.3.2", + "bitflags", "blake3", "borsh", "borsh-derive", @@ -7695,7 +7602,7 @@ dependencies = [ "assert_matches", "base64 0.13.0", "bincode", - "bitflags 1.3.2", + "bitflags", "borsh", "bs58 0.4.0", "bytemuck", @@ -7843,7 +7750,7 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77963e2aa8fadb589118c3aede2e78b6c4bcf1c01d588fbf33e915b390825fbd" dependencies = [ - "bitflags 1.3.2", + "bitflags", "byteorder", "hash-db", "hash256-std-hasher", @@ -8187,7 +8094,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "bitflags 1.3.2", + "bitflags", "core-foundation", "system-configuration-sys", ] @@ -8535,16 +8442,6 @@ dependencies = [ "syn 2.0.38", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.23.2" diff --git a/mm2src/mm2_main/Cargo.toml b/mm2src/mm2_main/Cargo.toml index 2f02767287..320019ab5e 100644 --- a/mm2src/mm2_main/Cargo.toml +++ b/mm2src/mm2_main/Cargo.toml @@ -126,7 +126,7 @@ coins_activation = { path = "../coins_activation", features = ["for-tests"] } mm2_test_helpers = { path = "../mm2_test_helpers" } mocktopus = "0.8.0" testcontainers = "0.15.0" -web3 = { git = "https://github.com/KomodoPlatform/rust-web3", tag = "v0.19.0", default-features = false, features = ["http-tls"] } +web3 = { git = "https://github.com/KomodoPlatform/rust-web3", tag = "v0.19.0", default-features = false, features = ["http-rustls-tls"] } ethabi = { version = "17.0.0" } [build-dependencies] From 7882e6ee1225145d1836cdc2842559c7a4d4821b Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 16 May 2024 20:46:28 +0700 Subject: [PATCH 029/233] review: send Http GET request to activate NFT --- mm2src/coins/eth/v2_activation.rs | 53 +++++++++++++------ mm2src/coins/nft.rs | 12 +++-- mm2src/coins/nft/nft_tests.rs | 8 +-- .../src/erc20_token_activation.rs | 4 +- .../src/eth_with_token_activation.rs | 6 +-- mm2src/common/common.rs | 2 +- mm2src/mm2_net/src/native_http.rs | 16 +++--- mm2src/mm2_net/src/transport.rs | 5 ++ mm2src/mm2_net/src/wasm/http.rs | 14 ++--- 9 files changed, 78 insertions(+), 42 deletions(-) diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 2a9944d9fd..52bc60143b 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -308,7 +308,11 @@ pub struct NftActivationRequest { #[derive(Clone, Deserialize)] #[serde(tag = "type", content = "info")] pub enum NftProviderEnum { - Moralis { url: Url }, + Moralis { + url: Url, + #[serde(default)] + proxy_auth: bool, + }, } /// Represents the protocol type for an Ethereum-based token, distinguishing between ERC-20 tokens and NFTs. @@ -442,6 +446,7 @@ impl EthCoin { pub async fn global_nft_from_platform_coin( &self, original_url: &Url, + proxy_auth: &bool, ) -> MmResult { let chain = Chain::from_ticker(self.ticker())?; let ticker = chain.to_nft_ticker().to_string(); @@ -452,20 +457,10 @@ impl EthCoin { // Todo: support HD wallet for NFTs, currently we get nfts for enabled address only and there might be some issues when activating NFTs while ETH is activated with HD wallet let my_address = self.derivation_method.single_addr_or_err().await?; - let my_address_str = display_eth_address(&my_address); - let secret = self.priv_key_policy().activated_key_or_err()?.secret().clone(); - let validation_generator = ProxyAuthValidationGenerator { - coin_ticker: chain.to_nft_ticker().to_string(), - secret, - address: my_address_str, - }; - let signed_message = EthCoin::generate_proxy_auth_signed_validation(validation_generator).map_err(|e| { - EthTokenActivationError::InternalError(format!( - "KomodefiProxyAuthValidation signed message generation failed. Error: {:?}", - e - )) - })?; - let nft_infos = get_nfts_for_activation(&chain, &my_address, original_url, &signed_message).await?; + + let signed_message = generate_signed_message(*proxy_auth, &chain, &my_address, self.priv_key_policy()).await?; + + let nft_infos = get_nfts_for_activation(&chain, &my_address, original_url, signed_message.as_ref()).await?; let global_nft = EthCoinImpl { ticker, @@ -498,6 +493,34 @@ impl EthCoin { } } +async fn generate_signed_message( + proxy_auth: bool, + chain: &Chain, + my_address: &Address, + priv_key_policy: &EthPrivKeyPolicy, +) -> MmResult, EthTokenActivationError> { + if !proxy_auth { + return Ok(None); + } + + let my_address_str = display_eth_address(my_address); + let secret = priv_key_policy.activated_key_or_err()?.secret().clone(); + let validation_generator = ProxyAuthValidationGenerator { + coin_ticker: chain.to_nft_ticker().to_string(), + secret, + address: my_address_str, + }; + + let signed_message = EthCoin::generate_proxy_auth_signed_validation(validation_generator).map_err(|e| { + EthTokenActivationError::InternalError(format!( + "KomodefiProxyAuthValidation signed message generation failed. Error: {:?}", + e + )) + })?; + + Ok(Some(signed_message)) +} + /// Activate eth coin from coin config and private key build policy, /// version 2 of the activation function, with no intrinsic tokens creation pub async fn eth_coin_from_conf_and_request_v2( diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index ee165cc70a..ac246bf248 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -256,6 +256,7 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft chain, orig_url: &req.url, url_antispam: &req.url_antispam, + // TODO make it optional signed_message: &signed_message, }; @@ -697,7 +698,7 @@ pub(crate) async fn get_nfts_for_activation( chain: &Chain, my_address: &Address, original_url: &Url, - signed_message: &KomodefiProxyAuthValidation, + signed_message: Option<&KomodefiProxyAuthValidation>, ) -> MmResult, GetNftInfoError> { let mut nfts_map = HashMap::new(); let uri_without_cursor = construct_moralis_uri_for_nft(original_url, ð_addr_to_hex(my_address), chain)?; @@ -710,9 +711,10 @@ pub(crate) async fn get_nfts_for_activation( if !cursor.is_empty() { uri.set_query(Some(&cursor)); } - let payload = moralis_payload_str(uri, signed_message.clone())?; - let response = send_post_request_to_uri(original_url.as_str(), payload).await?; - let response: Json = serde_json::from_slice(&response)?; + let payload = signed_message + .map(|msg| moralis_payload_str(uri, msg.clone())) + .transpose()?; + let response = send_request_to_uri(original_url.as_str(), payload.as_deref()).await?; if let Some(nfts_list) = response["result"].as_array() { process_nft_list_for_activation(nfts_list, chain, &mut nfts_map)?; // if cursor is not null, there are other NFTs on next page, @@ -1008,7 +1010,7 @@ fn construct_camo_url_with_token(token_uri: &str, url_antispam: &Url) -> Option< } async fn fetch_meta_from_url(url: Url) -> MmResult { - let response_meta = send_request_to_uri(url.as_str()).await?; + let response_meta = send_request_to_uri(url.as_str(), None).await?; serde_json::from_value(response_meta).map_err(|e| e.into()) } diff --git a/mm2src/coins/nft/nft_tests.rs b/mm2src/coins/nft/nft_tests.rs index 99fae76e1b..05f732a9ee 100644 --- a/mm2src/coins/nft/nft_tests.rs +++ b/mm2src/coins/nft/nft_tests.rs @@ -94,7 +94,7 @@ cross_test!(test_moralis_requests, { "{}/{}/nft?chain=POLYGON&format=decimal", MORALIS_API_ENDPOINT_TEST, TEST_WALLET_ADDR_EVM ); - let response_nft_list = send_request_to_uri(uri_nft_list.as_str()).await.unwrap(); + let response_nft_list = send_request_to_uri(uri_nft_list.as_str(), None).await.unwrap(); let nfts_list = response_nft_list["result"].as_array().unwrap(); for nft_json in nfts_list { let nft_moralis: NftFromMoralis = serde_json::from_str(&nft_json.to_string()).unwrap(); @@ -105,7 +105,7 @@ cross_test!(test_moralis_requests, { "{}/{}/nft/transfers?chain=POLYGON&format=decimal", MORALIS_API_ENDPOINT_TEST, TEST_WALLET_ADDR_EVM ); - let response_transfer_history = send_request_to_uri(uri_history.as_str()).await.unwrap(); + let response_transfer_history = send_request_to_uri(uri_history.as_str(), None).await.unwrap(); let mut transfer_list = response_transfer_history["result"].as_array().unwrap().clone(); assert!(!transfer_list.is_empty()); let first_transfer = transfer_list.remove(transfer_list.len() - 1); @@ -119,7 +119,7 @@ cross_test!(test_moralis_requests, { "{}/nft/0xed55e4477b795eaa9bb4bca24df42214e1a05c18/1111777?chain=POLYGON&format=decimal", MORALIS_API_ENDPOINT_TEST ); - let response_meta = send_request_to_uri(uri_meta.as_str()).await.unwrap(); + let response_meta = send_request_to_uri(uri_meta.as_str(), None).await.unwrap(); let nft_moralis: NftFromMoralis = serde_json::from_str(&response_meta.to_string()).unwrap(); assert_eq!(42563567, nft_moralis.block_number.0); }); @@ -155,7 +155,7 @@ cross_test!(test_antispam_scan_endpoints, { cross_test!(test_camo, { let hex_token_uri = hex::encode("https://tikimetadata.s3.amazonaws.com/tiki_box.json"); let uri_decode = format!("{}/url/decode/{}", BLOCKLIST_API_ENDPOINT, hex_token_uri); - let decode_res = send_request_to_uri(&uri_decode).await.unwrap(); + let decode_res = send_request_to_uri(&uri_decode, None).await.unwrap(); let uri_meta: UriMeta = serde_json::from_value(decode_res).unwrap(); assert_eq!( uri_meta.raw_image_url.unwrap(), diff --git a/mm2src/coins_activation/src/erc20_token_activation.rs b/mm2src/coins_activation/src/erc20_token_activation.rs index ab9c05c91a..82b89026bb 100644 --- a/mm2src/coins_activation/src/erc20_token_activation.rs +++ b/mm2src/coins_activation/src/erc20_token_activation.rs @@ -164,7 +164,9 @@ impl TokenActivationOps for EthCoin { )); } let nft_global = match &nft_init_params.provider { - NftProviderEnum::Moralis { url } => platform_coin.global_nft_from_platform_coin(url).await?, + NftProviderEnum::Moralis { url, proxy_auth } => { + platform_coin.global_nft_from_platform_coin(url, proxy_auth).await? + }, }; let nfts = nft_global.nfts_infos.lock().await.clone(); let init_result = EthTokenInitResult::Nft(NftInitResult { diff --git a/mm2src/coins_activation/src/eth_with_token_activation.rs b/mm2src/coins_activation/src/eth_with_token_activation.rs index de3346fb3e..487745419a 100644 --- a/mm2src/coins_activation/src/eth_with_token_activation.rs +++ b/mm2src/coins_activation/src/eth_with_token_activation.rs @@ -289,13 +289,13 @@ impl PlatformCoinWithTokensActivationOps for EthCoin { &self, activation_request: &Self::ActivationRequest, ) -> Result, MmError> { - let url = match &activation_request.nft_req { + let (url, proxy_auth) = match &activation_request.nft_req { Some(nft_req) => match &nft_req.provider { - NftProviderEnum::Moralis { url } => url, + NftProviderEnum::Moralis { url, proxy_auth } => (url, proxy_auth), }, None => return Ok(None), }; - let nft_global = self.global_nft_from_platform_coin(url).await?; + let nft_global = self.global_nft_from_platform_coin(url, proxy_auth).await?; Ok(Some(MmCoinEnum::EthCoin(nft_global))) } diff --git a/mm2src/common/common.rs b/mm2src/common/common.rs index 552abae1d4..2df0d6e358 100644 --- a/mm2src/common/common.rs +++ b/mm2src/common/common.rs @@ -193,7 +193,7 @@ cfg_wasm32! { const KOMODO_DEFI_FRAMEWORK_DIR_NAME: &str = ".kdf"; pub const X_GRPC_WEB: &str = "x-grpc-web"; -pub const X_API_KEY: &str = "X-API-Key"; +pub const X_AUTH_PAYLOAD: &str = "X-Auth-Payload"; pub const APPLICATION_JSON: &str = "application/json"; pub const APPLICATION_GRPC_WEB: &str = "application/grpc-web"; pub const APPLICATION_GRPC_WEB_PROTO: &str = "application/grpc-web+proto"; diff --git a/mm2src/mm2_net/src/native_http.rs b/mm2src/mm2_net/src/native_http.rs index 3f3e9bdec6..94f37ef65c 100644 --- a/mm2src/mm2_net/src/native_http.rs +++ b/mm2src/mm2_net/src/native_http.rs @@ -20,7 +20,7 @@ use hyper::{Body, Client}; use serde_json::Value as Json; use common::wio::{drive03, HYPER}; -use common::APPLICATION_JSON; +use common::{APPLICATION_JSON, X_AUTH_PAYLOAD}; use mm2_err_handle::prelude::*; use super::transport::{GetInfoFromUriError, SlurpError, SlurpResult, SlurpResultJson}; @@ -157,8 +157,7 @@ pub trait SlurpHttpClient { let body_bytes = hyper::body::to_bytes(response.into_body()) .await .map_to_mm(|e| SlurpError::from_hyper_error(e, uri.clone()))?; - let body_str = String::from_utf8(body_bytes.to_vec()).map_to_mm(|e| SlurpError::Internal(e.to_string()))?; - let body: Json = serde_json::from_str(&body_str)?; + let body: Json = serde_json::from_slice(&body_bytes)?; Ok((status, headers, body)) } @@ -236,12 +235,15 @@ impl From for SlurpError { /// # Errors /// /// Returns an error if the HTTP status code of the response is not in the 2xx range. -pub async fn send_request_to_uri(uri: &str) -> MmResult { - let request = http::Request::builder() +pub async fn send_request_to_uri(uri: &str, auth_header: Option<&str>) -> MmResult { + let mut request_builder = http::Request::builder() .method("GET") .uri(uri) - .header(header::ACCEPT, HeaderValue::from_static(APPLICATION_JSON)) - .body(Body::empty())?; + .header(header::ACCEPT, HeaderValue::from_static(APPLICATION_JSON)); + if let Some(auth_header) = auth_header { + request_builder = request_builder.header(X_AUTH_PAYLOAD, HeaderValue::from_str(auth_header)?); + } + let request = request_builder.body(Body::empty())?; let (status, _header, body) = slurp_req_body(request).await?; if !status.is_success() { diff --git a/mm2src/mm2_net/src/transport.rs b/mm2src/mm2_net/src/transport.rs index 35bbab434b..dd966feb84 100644 --- a/mm2src/mm2_net/src/transport.rs +++ b/mm2src/mm2_net/src/transport.rs @@ -120,6 +120,11 @@ impl From for GetInfoFromUriError { } } +#[cfg(not(target_arch = "wasm32"))] +impl From for GetInfoFromUriError { + fn from(e: hyper::header::InvalidHeaderValue) -> Self { GetInfoFromUriError::Internal(e.to_string()) } +} + /// Sends a POST request to the given URI and expects a 2xx status code in response. /// /// # Errors diff --git a/mm2src/mm2_net/src/wasm/http.rs b/mm2src/mm2_net/src/wasm/http.rs index e836da8c68..4795af346c 100644 --- a/mm2src/mm2_net/src/wasm/http.rs +++ b/mm2src/mm2_net/src/wasm/http.rs @@ -1,7 +1,7 @@ use crate::transport::{GetInfoFromUriError, SlurpError, SlurpResult}; use crate::wasm::body_stream::ResponseBody; use common::executor::spawn_local; -use common::{drop_mutability, stringify_js_error, APPLICATION_JSON}; +use common::{drop_mutability, stringify_js_error, APPLICATION_JSON, X_AUTH_PAYLOAD}; use futures::channel::oneshot; use gstuff::ERRL; use http::header::{ACCEPT, CONTENT_TYPE}; @@ -384,7 +384,7 @@ impl RequestBody { /// # Errors /// /// Returns an error if the HTTP status code of the response is not in the 2xx range. -pub async fn send_request_to_uri(uri: &str) -> MmResult { +pub async fn send_request_to_uri(uri: &str, auth_header: Option<&str>) -> MmResult { macro_rules! try_or { ($exp:expr, $errtype:ident) => { match $exp { @@ -394,10 +394,12 @@ pub async fn send_request_to_uri(uri: &str) -> MmResult Date: Fri, 17 May 2024 15:32:45 +0700 Subject: [PATCH 030/233] review: support GET requests to KomodoDeFi Proxy layer and to 3rd API directly --- mm2src/coins/eth/v2_activation.rs | 46 ++++++++++++---- mm2src/coins/nft.rs | 91 +++++++++++++++---------------- mm2src/coins/nft/nft_errors.rs | 10 ++++ mm2src/coins/nft/nft_structs.rs | 2 + 4 files changed, 91 insertions(+), 58 deletions(-) diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 52bc60143b..c66f651b15 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -262,6 +262,32 @@ impl From for EthTokenActivationError { fn from(e: PrivKeyPolicyNotAllowed) -> Self { EthTokenActivationError::PrivKeyPolicyNotAllowed(e) } } +impl From for EthTokenActivationError { + fn from(e: GenerateSignedMessageError) -> Self { + match e { + GenerateSignedMessageError::InternalError(e) => EthTokenActivationError::InternalError(e), + GenerateSignedMessageError::PrivKeyPolicyNotAllowed(e) => { + EthTokenActivationError::PrivKeyPolicyNotAllowed(e) + }, + } + } +} + +#[derive(Display, Serialize)] +pub enum GenerateSignedMessageError { + #[display(fmt = "Internal: {}", _0)] + InternalError(String), + PrivKeyPolicyNotAllowed(PrivKeyPolicyNotAllowed), +} + +impl From for GenerateSignedMessageError { + fn from(e: PrivKeyPolicyNotAllowed) -> Self { GenerateSignedMessageError::PrivKeyPolicyNotAllowed(e) } +} + +impl From for GenerateSignedMessageError { + fn from(e: SignatureError) -> Self { GenerateSignedMessageError::InternalError(e.to_string()) } +} + /// Represents the parameters required for activating either an ERC-20 token or an NFT on the Ethereum platform. #[derive(Clone, Deserialize)] #[serde(untagged)] @@ -458,7 +484,9 @@ impl EthCoin { // Todo: support HD wallet for NFTs, currently we get nfts for enabled address only and there might be some issues when activating NFTs while ETH is activated with HD wallet let my_address = self.derivation_method.single_addr_or_err().await?; - let signed_message = generate_signed_message(*proxy_auth, &chain, &my_address, self.priv_key_policy()).await?; + let my_address_str = display_eth_address(&my_address); + let signed_message = + generate_signed_message(*proxy_auth, &chain, my_address_str, self.priv_key_policy()).await?; let nft_infos = get_nfts_for_activation(&chain, &my_address, original_url, signed_message.as_ref()).await?; @@ -493,30 +521,24 @@ impl EthCoin { } } -async fn generate_signed_message( +pub(crate) async fn generate_signed_message( proxy_auth: bool, chain: &Chain, - my_address: &Address, + my_address: String, priv_key_policy: &EthPrivKeyPolicy, -) -> MmResult, EthTokenActivationError> { +) -> MmResult, GenerateSignedMessageError> { if !proxy_auth { return Ok(None); } - let my_address_str = display_eth_address(my_address); let secret = priv_key_policy.activated_key_or_err()?.secret().clone(); let validation_generator = ProxyAuthValidationGenerator { coin_ticker: chain.to_nft_ticker().to_string(), secret, - address: my_address_str, + address: my_address, }; - let signed_message = EthCoin::generate_proxy_auth_signed_validation(validation_generator).map_err(|e| { - EthTokenActivationError::InternalError(format!( - "KomodefiProxyAuthValidation signed message generation failed. Error: {:?}", - e - )) - })?; + let signed_message = EthCoin::generate_proxy_auth_signed_validation(validation_generator)?; Ok(Some(signed_message)) } diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index ac246bf248..b08ad4836d 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -16,7 +16,7 @@ use nft_structs::{Chain, ContractType, ConvertChain, Nft, NftFromMoralis, NftLis TransactionNftDetails, UpdateNftReq, WithdrawNftReq}; use crate::eth::{eth_addr_to_hex, get_eth_address, withdraw_erc1155, withdraw_erc721, EthCoin, EthCoinType, - EthTxFeeDetails, KomodoDefiAuthMessages}; + EthTxFeeDetails}; use crate::hd_wallet::HDPathAccountToAddressId; use crate::nft::nft_errors::{ClearNftDbError, MetaFromUrlError, ProtectFromSpamError, TransferConfirmationsError, UpdateSpamPhishingError}; @@ -31,7 +31,7 @@ use ethereum_types::{Address, H256}; use futures::compat::Future01CompatExt; use futures::future::try_join_all; use mm2_err_handle::map_to_mm::MapToMmResult; -use mm2_net::transport::{send_post_request_to_uri, KomodefiProxyAuthValidation, ProxyAuthValidationGenerator}; +use mm2_net::transport::{send_post_request_to_uri, KomodefiProxyAuthValidation}; use mm2_number::BigUint; use regex::Regex; use serde::Deserialize; @@ -44,6 +44,7 @@ use web3::types::TransactionId; #[cfg(not(target_arch = "wasm32"))] use mm2_net::native_http::send_request_to_uri; +use crate::eth::v2_activation::generate_signed_message; #[cfg(target_arch = "wasm32")] use mm2_net::wasm::http::send_request_to_uri; @@ -238,26 +239,13 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft }, }; let my_address = eth_coin.my_address()?; - let secret = eth_coin.priv_key_policy.activated_key_or_err()?.secret().clone(); - - let validation_generator = ProxyAuthValidationGenerator { - coin_ticker: chain.to_nft_ticker().to_string(), - secret, - address: my_address, - }; - let signed_message = EthCoin::generate_proxy_auth_signed_validation(validation_generator).map_err(|e| { - UpdateNftError::Internal(format!( - "KomodefiProxyAuthValidation signed message generation failed. Error: {:?}", - e - )) - })?; - + let signed_message = + generate_signed_message(req.proxy_auth, chain, my_address, ð_coin.priv_key_policy).await?; let wrapper = UrlSignWrapper { chain, orig_url: &req.url, url_antispam: &req.url_antispam, - // TODO make it optional - signed_message: &signed_message, + signed_message: signed_message.as_ref(), }; let nft_transfers = get_moralis_nft_transfers(&ctx, from_block, eth_coin, &wrapper).await?; @@ -275,7 +263,7 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft continue; }, Err(_) => { - // if there is an error, then NFT LIST table doesnt exist, so we need to cache nft list from moralis. + // if there is an error, then NFT LIST table doesn't exist, so we need to cache nft list from moralis. NftListStorageOps::init(&storage, chain).await?; let nft_list = cache_nfts_from_moralis(&ctx, &storage, &wrapper).await?; update_meta_in_transfers(&storage, chain, nft_list).await?; @@ -487,25 +475,13 @@ pub async fn refresh_nft_metadata(ctx: MmArc, req: RefreshMetadataReq) -> MmResu }, }; let my_address = eth_coin.my_address()?; - let secret = eth_coin.priv_key_policy.activated_key_or_err()?.secret().clone(); - - let validation_generator = ProxyAuthValidationGenerator { - coin_ticker: req.chain.to_nft_ticker().to_string(), - secret, - address: my_address, - }; - let signed_message = EthCoin::generate_proxy_auth_signed_validation(validation_generator).map_err(|e| { - UpdateNftError::Internal(format!( - "KomodefiProxyAuthValidation signed message generation failed. Error: {:?}", - e - )) - })?; - + let signed_message = + generate_signed_message(req.proxy_auth, &req.chain, my_address, ð_coin.priv_key_policy).await?; let wrapper = UrlSignWrapper { chain: &req.chain, orig_url: &req.url, url_antispam: &req.url_antispam, - signed_message: &signed_message, + signed_message: signed_message.as_ref(), }; let token_address_str = eth_addr_to_hex(&req.token_address); @@ -664,9 +640,15 @@ async fn get_moralis_nft_list(ctx: &MmArc, wrapper: &UrlSignWrapper<'_>) -> MmRe if !cursor.is_empty() { uri.set_query(Some(&cursor)); } - let payload = moralis_payload_str(uri, wrapper.signed_message.clone())?; - let response = send_post_request_to_uri(wrapper.orig_url.as_str(), payload).await?; - let response: Json = serde_json::from_slice(&response)?; + let payload = wrapper + .signed_message + .map(|msg| moralis_payload_str(uri.clone(), msg.clone())) + .transpose()?; + let response = if wrapper.signed_message.is_some() { + send_request_to_uri(wrapper.orig_url.as_str(), payload.as_deref()).await? + } else { + send_request_to_uri(uri.as_str(), payload.as_deref()).await? + }; if let Some(nfts_list) = response["result"].as_array() { for nft_json in nfts_list { let nft_moralis = NftFromMoralis::deserialize(nft_json)?; @@ -712,9 +694,13 @@ pub(crate) async fn get_nfts_for_activation( uri.set_query(Some(&cursor)); } let payload = signed_message - .map(|msg| moralis_payload_str(uri, msg.clone())) + .map(|msg| moralis_payload_str(uri.clone(), msg.clone())) .transpose()?; - let response = send_request_to_uri(original_url.as_str(), payload.as_deref()).await?; + let response = if signed_message.is_some() { + send_request_to_uri(original_url.as_str(), payload.as_deref()).await? + } else { + send_request_to_uri(uri.as_str(), payload.as_deref()).await? + }; if let Some(nfts_list) = response["result"].as_array() { process_nft_list_for_activation(nfts_list, chain, &mut nfts_map)?; // if cursor is not null, there are other NFTs on next page, @@ -797,9 +783,15 @@ async fn get_moralis_nft_transfers( if !cursor.is_empty() { uri.set_query(Some(&cursor)); } - let payload = moralis_payload_str(uri, wrapper.signed_message.clone())?; - let response = send_post_request_to_uri(wrapper.orig_url.as_str(), payload).await?; - let response: Json = serde_json::from_slice(&response)?; + let payload = wrapper + .signed_message + .map(|msg| moralis_payload_str(uri.clone(), msg.clone())) + .transpose()?; + let response = if wrapper.signed_message.is_some() { + send_request_to_uri(wrapper.orig_url.as_str(), payload.as_deref()).await? + } else { + send_request_to_uri(uri.as_str(), payload.as_deref()).await? + }; if let Some(transfer_list) = response["result"].as_array() { process_transfer_list(transfer_list, chain, wallet_address.as_str(), ð_coin, &mut res_list).await?; // if the cursor is not null, there are other NFTs transfers on next page, @@ -930,9 +922,16 @@ async fn get_moralis_metadata( .append_pair(MORALIS_FORMAT_QUERY_NAME, MORALIS_FORMAT_QUERY_VALUE); drop_mutability!(uri); - let payload = moralis_payload_str(uri, wrapper.signed_message.clone())?; - let response = send_post_request_to_uri(wrapper.orig_url.as_str(), payload).await?; - let response: Json = serde_json::from_slice(&response)?; + let payload = wrapper + .signed_message + .map(|msg| moralis_payload_str(uri.clone(), msg.clone())) + .transpose()?; + let response = if wrapper.signed_message.is_some() { + send_request_to_uri(wrapper.orig_url.as_str(), payload.as_deref()).await? + } else { + send_request_to_uri(uri.as_str(), payload.as_deref()).await? + }; + let nft_moralis: NftFromMoralis = serde_json::from_str(&response.to_string())?; let contract_type = match nft_moralis.contract_type { Some(contract_type) => contract_type, @@ -1613,5 +1612,5 @@ struct UrlSignWrapper<'a> { chain: &'a Chain, orig_url: &'a Url, url_antispam: &'a Url, - signed_message: &'a KomodefiProxyAuthValidation, + signed_message: Option<&'a KomodefiProxyAuthValidation>, } diff --git a/mm2src/coins/nft/nft_errors.rs b/mm2src/coins/nft/nft_errors.rs index 3ae031b6f5..6a1741985c 100644 --- a/mm2src/coins/nft/nft_errors.rs +++ b/mm2src/coins/nft/nft_errors.rs @@ -1,4 +1,5 @@ use super::MoralisPayloadErr; +use crate::eth::v2_activation::GenerateSignedMessageError; use crate::eth::GetEthAddressError; #[cfg(target_arch = "wasm32")] use crate::nft::storage::wasm::WasmNftCacheError; @@ -256,6 +257,15 @@ impl From for UpdateNftError { fn from(e: PrivKeyPolicyNotAllowed) -> Self { Self::PrivKeyPolicyNotAllowed(e) } } +impl From for UpdateNftError { + fn from(e: GenerateSignedMessageError) -> Self { + match e { + GenerateSignedMessageError::InternalError(e) => UpdateNftError::Internal(e), + GenerateSignedMessageError::PrivKeyPolicyNotAllowed(e) => UpdateNftError::PrivKeyPolicyNotAllowed(e), + } + } +} + impl HttpStatusCode for UpdateNftError { fn status_code(&self) -> StatusCode { match self { diff --git a/mm2src/coins/nft/nft_structs.rs b/mm2src/coins/nft/nft_structs.rs index 155685d768..92e9c62d30 100644 --- a/mm2src/coins/nft/nft_structs.rs +++ b/mm2src/coins/nft/nft_structs.rs @@ -98,6 +98,7 @@ pub struct RefreshMetadataReq { /// URL used to validate if the fetched contract addresses are associated /// with spam contracts or if domain fields in the fetched metadata match known phishing domains. pub(crate) url_antispam: Url, + pub(crate) proxy_auth: bool, } /// Represents blockchains which are supported by NFT feature. @@ -660,6 +661,7 @@ pub struct UpdateNftReq { /// URL used to validate if the fetched contract addresses are associated /// with spam contracts or if domain fields in the fetched metadata match known phishing domains. pub(crate) url_antispam: Url, + pub(crate) proxy_auth: bool, } /// Represents a unique identifier for an NFT, consisting of its token address and token ID. From ff92a20030e554a75bd85e7184a82fd62296958e Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 17 May 2024 15:54:48 +0700 Subject: [PATCH 031/233] impl build_and_send_request func to avoid code repetition --- mm2src/coins/nft.rs | 60 ++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index b08ad4836d..e18f9d8cd5 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -640,15 +640,8 @@ async fn get_moralis_nft_list(ctx: &MmArc, wrapper: &UrlSignWrapper<'_>) -> MmRe if !cursor.is_empty() { uri.set_query(Some(&cursor)); } - let payload = wrapper - .signed_message - .map(|msg| moralis_payload_str(uri.clone(), msg.clone())) - .transpose()?; - let response = if wrapper.signed_message.is_some() { - send_request_to_uri(wrapper.orig_url.as_str(), payload.as_deref()).await? - } else { - send_request_to_uri(uri.as_str(), payload.as_deref()).await? - }; + + let response = build_and_send_request(&uri, wrapper.orig_url, wrapper.signed_message).await?; if let Some(nfts_list) = response["result"].as_array() { for nft_json in nfts_list { let nft_moralis = NftFromMoralis::deserialize(nft_json)?; @@ -693,14 +686,8 @@ pub(crate) async fn get_nfts_for_activation( if !cursor.is_empty() { uri.set_query(Some(&cursor)); } - let payload = signed_message - .map(|msg| moralis_payload_str(uri.clone(), msg.clone())) - .transpose()?; - let response = if signed_message.is_some() { - send_request_to_uri(original_url.as_str(), payload.as_deref()).await? - } else { - send_request_to_uri(uri.as_str(), payload.as_deref()).await? - }; + + let response = build_and_send_request(&uri, original_url, signed_message).await?; if let Some(nfts_list) = response["result"].as_array() { process_nft_list_for_activation(nfts_list, chain, &mut nfts_map)?; // if cursor is not null, there are other NFTs on next page, @@ -783,15 +770,8 @@ async fn get_moralis_nft_transfers( if !cursor.is_empty() { uri.set_query(Some(&cursor)); } - let payload = wrapper - .signed_message - .map(|msg| moralis_payload_str(uri.clone(), msg.clone())) - .transpose()?; - let response = if wrapper.signed_message.is_some() { - send_request_to_uri(wrapper.orig_url.as_str(), payload.as_deref()).await? - } else { - send_request_to_uri(uri.as_str(), payload.as_deref()).await? - }; + + let response = build_and_send_request(&uri, wrapper.orig_url, wrapper.signed_message).await?; if let Some(transfer_list) = response["result"].as_array() { process_transfer_list(transfer_list, chain, wallet_address.as_str(), ð_coin, &mut res_list).await?; // if the cursor is not null, there are other NFTs transfers on next page, @@ -922,16 +902,7 @@ async fn get_moralis_metadata( .append_pair(MORALIS_FORMAT_QUERY_NAME, MORALIS_FORMAT_QUERY_VALUE); drop_mutability!(uri); - let payload = wrapper - .signed_message - .map(|msg| moralis_payload_str(uri.clone(), msg.clone())) - .transpose()?; - let response = if wrapper.signed_message.is_some() { - send_request_to_uri(wrapper.orig_url.as_str(), payload.as_deref()).await? - } else { - send_request_to_uri(uri.as_str(), payload.as_deref()).await? - }; - + let response = build_and_send_request(&uri, wrapper.orig_url, wrapper.signed_message).await?; let nft_moralis: NftFromMoralis = serde_json::from_str(&response.to_string())?; let contract_type = match nft_moralis.contract_type { Some(contract_type) => contract_type, @@ -1614,3 +1585,20 @@ struct UrlSignWrapper<'a> { url_antispam: &'a Url, signed_message: Option<&'a KomodefiProxyAuthValidation>, } + +async fn build_and_send_request( + uri: &Url, + original_url: &Url, + signed_message: Option<&KomodefiProxyAuthValidation>, +) -> MmResult { + let payload = signed_message + .map(|msg| moralis_payload_str(uri.clone(), msg.clone())) + .transpose()?; + let url_to_use = if signed_message.is_some() { + original_url.as_str() + } else { + uri.as_str() + }; + let response = send_request_to_uri(url_to_use, payload.as_deref()).await?; + Ok(response) +} From a2c47f8680d536038b2dd168f6500375efeb65b8 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 17 May 2024 17:09:21 +0700 Subject: [PATCH 032/233] review: panic in wait_for_geth_node_ready if Deth node is not ready after several attempts --- mm2src/mm2_main/tests/docker_tests_main.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests_main.rs b/mm2src/mm2_main/tests/docker_tests_main.rs index 2a3377f11a..1584550024 100644 --- a/mm2src/mm2_main/tests/docker_tests_main.rs +++ b/mm2src/mm2_main/tests/docker_tests_main.rs @@ -22,6 +22,7 @@ extern crate serde_json; #[cfg(test)] extern crate ser_error_derive; #[cfg(test)] extern crate test; +use common::custom_futures::timeout::FutureTimerExt; use std::io::{BufRead, BufReader}; use std::process::Command; use std::time::Duration; @@ -105,21 +106,23 @@ pub fn docker_tests_runner(tests: &[&TestDescAndFn]) { fn wait_for_geth_node_ready() { let mut attempts = 0; loop { - if attempts >= 10 { - println!("Failed to connect to Geth node after several attempts."); - break; + if attempts >= 5 { + panic!("Failed to connect to Geth node after several attempts."); } - match block_on(GETH_WEB3.eth().block_number()) { - Ok(block_number) => { + match block_on(GETH_WEB3.eth().block_number().timeout(Duration::from_secs(6))) { + Ok(Ok(block_number)) => { println!("Geth node is ready, latest block number: {:?}", block_number); break; }, - Err(e) => { + Ok(Err(e)) => { println!("Failed to connect to Geth node: {:?}, retrying...", e); - attempts += 1; - thread::sleep(Duration::from_secs(1)); + }, + Err(_) => { + println!("Connection to Geth node timed out, retrying..."); }, } + attempts += 1; + thread::sleep(Duration::from_secs(1)); } } From 9c3ff0703e0a192bd2b5056b735ccf740f972a7d Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 21 May 2024 14:43:51 +0700 Subject: [PATCH 033/233] merge: fmt, log tx_hash() in NFT payments instead of bytes, import ethcore_transaction::Action in eth_docker_tests.rs separately --- mm2src/coins/eth.rs | 2 +- .../tests/docker_tests/eth_docker_tests.rs | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index f25d6cad60..03fb33b49b 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -79,7 +79,7 @@ use instant::Instant; use keys::Public as HtlcPubKey; use mm2_core::mm_ctx::{MmArc, MmWeak}; use mm2_event_stream::behaviour::{EventBehaviour, EventInitStatus}; -use mm2_net::transport::{slurp_url, KomodefiProxyAuthValidation, ProxyAuthValidationGenerator, SlurpError}; +use mm2_net::transport::{KomodefiProxyAuthValidation, ProxyAuthValidationGenerator}; use mm2_number::bigdecimal_custom::CheckedDivision; use mm2_number::{BigDecimal, BigUint, MmNumber}; #[cfg(test)] use mocktopus::macros::*; diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index c52a24de69..d250a708b5 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -6,16 +6,16 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC7 SEPOLIA_NONCE_LOCK, SEPOLIA_RPC_URL, SEPOLIA_WEB3}; use crate::common::Future01CompatExt; use bitcrypto::{dhash160, sha256}; -use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_request, Action, EthCoin, SignedEthTx, - ERC20_ABI}; +use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_request, EthCoin, SignedEthTx, ERC20_ABI}; use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; -use coins::{lp_coinfind,CoinsContext, CoinProtocol, MmCoinEnum,MmCoinStruct, CoinWithDerivationMethod, ConfirmPaymentInput, DerivationMethod, Eip1559Ops, - FoundSwapTxSpend, MakerNftSwapOpsV2, MarketCoinOps, NftSwapInfo, ParseCoinAssocTypes, PrivKeyBuildPolicy, - RefundPaymentArgs, SearchForSwapTxSpendInput, SendNftMakerPaymentArgs, SendPaymentArgs, - SpendNftMakerPaymentArgs, SpendPaymentArgs, SwapOps, SwapTxFeePolicy, SwapTxTypeWithSecretHash, ToBytes, - Transaction, ValidateNftMakerPaymentArgs}; +use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, ConfirmPaymentInput, DerivationMethod, + Eip1559Ops, FoundSwapTxSpend, MakerNftSwapOpsV2, MarketCoinOps, MmCoinEnum, MmCoinStruct, NftSwapInfo, + ParseCoinAssocTypes, PrivKeyBuildPolicy, RefundPaymentArgs, SearchForSwapTxSpendInput, + SendNftMakerPaymentArgs, SendPaymentArgs, SpendNftMakerPaymentArgs, SpendPaymentArgs, SwapOps, + SwapTxFeePolicy, SwapTxTypeWithSecretHash, ToBytes, Transaction, ValidateNftMakerPaymentArgs}; use common::{block_on, now_sec}; use crypto::Secp256k1Secret; +use ethcore_transaction::Action; use ethereum_types::U256; use futures01::Future; use mm2_core::mm_ctx::MmArc; @@ -143,7 +143,7 @@ fn fill_erc20(to_addr: Address, amount: U256) { } #[allow(dead_code)] -pub(crate) fn mint_erc721(to_addr: Address, token_id: U256) { +fn mint_erc721(to_addr: Address, token_id: U256) { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc721_contract = Contract::from_json(GETH_WEB3.eth(), erc721_contract(), ERC721_TEST_ABI.as_bytes()).unwrap(); @@ -171,7 +171,7 @@ pub(crate) fn mint_erc721(to_addr: Address, token_id: U256) { ); } -pub(crate) fn erc712_owner(token_id: U256) -> Address { +fn erc712_owner(token_id: U256) -> Address { let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); let erc721_contract = Contract::from_json(SEPOLIA_WEB3.eth(), sepolia_erc721(), ERC721_TEST_ABI.as_bytes()).unwrap(); @@ -179,7 +179,7 @@ pub(crate) fn erc712_owner(token_id: U256) -> Address { } #[allow(dead_code)] -pub(crate) fn mint_erc1155(to_addr: Address, token_id: U256, amount: U256) { +fn mint_erc1155(to_addr: Address, token_id: U256, amount: U256) { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc1155_contract = Contract::from_json(GETH_WEB3.eth(), erc1155_contract(), ERC1155_TEST_ABI.as_bytes()).unwrap(); @@ -215,7 +215,7 @@ pub(crate) fn mint_erc1155(to_addr: Address, token_id: U256, amount: U256) { ); } -pub(crate) fn erc1155_balance(wallet_addr: Address, token_id: U256) -> U256 { +fn erc1155_balance(wallet_addr: Address, token_id: U256) -> U256 { let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); let erc1155_contract = Contract::from_json(SEPOLIA_WEB3.eth(), sepolia_erc1155(), ERC1155_TEST_ABI.as_bytes()).unwrap(); @@ -939,7 +939,7 @@ fn send_and_spend_erc721_maker_payment() { let maker_payment = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); log!( "Maker sent ERC721 NFT payment, tx hash: {:02x}", - maker_payment.tx_hash_as_bytes() + maker_payment.tx_hash() ); let confirm_input = ConfirmPaymentInput { @@ -1055,7 +1055,7 @@ fn send_and_spend_erc1155_maker_payment() { let maker_payment = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); log!( "Maker sent ERC1155 NFT payment, tx hash: {:02x}", - maker_payment.tx_hash_as_bytes() + maker_payment.tx_hash() ); let confirm_input = ConfirmPaymentInput { From 0bedba31dc85b9057bd4dfbb41511ccd1fdab20e Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 23 May 2024 17:49:17 +0700 Subject: [PATCH 034/233] send only signed message as header in nft --- mm2src/coins/nft.rs | 87 ++++++++++------------------------ mm2src/coins/nft/nft_errors.rs | 4 +- 2 files changed, 27 insertions(+), 64 deletions(-) diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index 0f72fabf39..4d432235a9 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -25,7 +25,6 @@ use crate::nft::nft_structs::{build_nft_with_empty_meta, BuildNftFields, ClearNf use crate::nft::storage::{NftListStorageOps, NftTransferHistoryStorageOps}; use common::log::error; use common::parse_rfc3339_to_timestamp; -use enum_derives::EnumFromStringify; use ethereum_types::{Address, H256}; use futures::compat::Future01CompatExt; use futures::future::try_join_all; @@ -47,7 +46,8 @@ use crate::eth::v2_activation::generate_signed_message; #[cfg(target_arch = "wasm32")] use mm2_net::wasm::http::send_request_to_uri; -const MORALIS_API_ENDPOINT: &str = "api/v2"; +const MORALIS_API: &str = "api"; +const MORALIS_ENDPOINT_V: &str = "v2"; /// query parameters for moralis request: The format of the token ID const MORALIS_FORMAT_QUERY_NAME: &str = "format"; const MORALIS_FORMAT_QUERY_VALUE: &str = "decimal"; @@ -635,12 +635,8 @@ async fn get_moralis_nft_list(ctx: &MmArc, wrapper: &UrlSignWrapper<'_>) -> MmRe let mut cursor = String::new(); loop { // Create a new URL instance from uri_without_cursor and modify its query to include the cursor if present - let mut uri = uri_without_cursor.clone(); - if !cursor.is_empty() { - uri.set_query(Some(&cursor)); - } - - let response = build_and_send_request(&uri, wrapper.orig_url, wrapper.signed_message).await?; + let uri = format!("{}{}", uri_without_cursor, cursor); + let response = build_and_send_request(uri.as_str(), wrapper.signed_message).await?; if let Some(nfts_list) = response["result"].as_array() { for nft_json in nfts_list { let nft_moralis = NftFromMoralis::deserialize(nft_json)?; @@ -656,7 +652,7 @@ async fn get_moralis_nft_list(ctx: &MmArc, wrapper: &UrlSignWrapper<'_>) -> MmRe // if cursor is not null, there are other NFTs on next page, // and we need to send new request with cursor to get info from the next page. if let Some(cursor_res) = response["cursor"].as_str() { - cursor = format!("cursor={}", cursor_res); + cursor = format!("&cursor={}", cursor_res); continue; } else { break; @@ -671,28 +667,24 @@ async fn get_moralis_nft_list(ctx: &MmArc, wrapper: &UrlSignWrapper<'_>) -> MmRe pub(crate) async fn get_nfts_for_activation( chain: &Chain, my_address: &Address, - original_url: &Url, + orig_url: &Url, signed_message: Option<&KomodefiProxyAuthValidation>, ) -> MmResult, GetNftInfoError> { let mut nfts_map = HashMap::new(); - let uri_without_cursor = construct_moralis_uri_for_nft(original_url, ð_addr_to_hex(my_address), chain)?; + let uri_without_cursor = construct_moralis_uri_for_nft(orig_url, ð_addr_to_hex(my_address), chain)?; // The cursor returned in the previous response (used for getting the next page). let mut cursor = String::new(); loop { // Create a new URL instance from uri_without_cursor and modify its query to include the cursor if present - let mut uri = uri_without_cursor.clone(); - if !cursor.is_empty() { - uri.set_query(Some(&cursor)); - } - - let response = build_and_send_request(&uri, original_url, signed_message).await?; + let uri = format!("{}{}", uri_without_cursor, cursor); + let response = build_and_send_request(uri.as_str(), signed_message).await?; if let Some(nfts_list) = response["result"].as_array() { process_nft_list_for_activation(nfts_list, chain, &mut nfts_map)?; // if cursor is not null, there are other NFTs on next page, // and we need to send new request with cursor to get info from the next page. if let Some(cursor_res) = response["cursor"].as_str() { - cursor = format!("cursor={}", cursor_res); + cursor = format!("&cursor={}", cursor_res); continue; } else { break; @@ -742,10 +734,11 @@ async fn get_moralis_nft_transfers( let my_address = get_eth_address(ctx, &conf, ticker, &HDPathAccountToAddressId::default()).await?; let mut uri_without_cursor = wrapper.orig_url.clone(); - uri_without_cursor.set_path(MORALIS_API_ENDPOINT); uri_without_cursor .path_segments_mut() .map_to_mm(|_| GetNftInfoError::Internal("Invalid URI".to_string()))? + .push(MORALIS_API) + .push(MORALIS_ENDPOINT_V) .push(&my_address.wallet_address) .push("nft") .push("transfers"); @@ -765,18 +758,14 @@ async fn get_moralis_nft_transfers( let wallet_address = my_address.wallet_address; loop { // Create a new URL instance from uri_without_cursor and modify its query to include the cursor if present - let mut uri = uri_without_cursor.clone(); - if !cursor.is_empty() { - uri.set_query(Some(&cursor)); - } - - let response = build_and_send_request(&uri, wrapper.orig_url, wrapper.signed_message).await?; + let uri = format!("{}{}", uri_without_cursor, cursor); + let response = build_and_send_request(uri.as_str(), wrapper.signed_message).await?; if let Some(transfer_list) = response["result"].as_array() { process_transfer_list(transfer_list, chain, wallet_address.as_str(), ð_coin, &mut res_list).await?; // if the cursor is not null, there are other NFTs transfers on next page, // and we need to send new request with cursor to get info from the next page. if let Some(cursor_res) = response["cursor"].as_str() { - cursor = format!("cursor={}", cursor_res); + cursor = format!("&cursor={}", cursor_res); continue; } else { break; @@ -892,7 +881,7 @@ async fn get_fee_details(eth_coin: &EthCoin, transaction_hash: &str) -> Option MmResult { let mut uri = wrapper.orig_url.clone(); let chain = wrapper.chain; - uri.set_path(MORALIS_API_ENDPOINT); uri.path_segments_mut() .map_to_mm(|_| GetNftInfoError::Internal("Invalid URI".to_string()))? + .push(MORALIS_API) + .push(MORALIS_ENDPOINT_V) .push("nft") .push(&token_address) .push(&token_id.to_string()); @@ -911,7 +901,7 @@ async fn get_moralis_metadata( .append_pair(MORALIS_FORMAT_QUERY_NAME, MORALIS_FORMAT_QUERY_VALUE); drop_mutability!(uri); - let response = build_and_send_request(&uri, wrapper.orig_url, wrapper.signed_message).await?; + let response = build_and_send_request(uri.as_str(), wrapper.signed_message).await?; let nft_moralis: NftFromMoralis = serde_json::from_str(&response.to_string())?; let contract_type = match nft_moralis.contract_type { Some(contract_type) => contract_type, @@ -1556,11 +1546,12 @@ where Ok(()) } -fn construct_moralis_uri_for_nft(base_url: &Url, address: &str, chain: &Chain) -> MmResult { - let mut uri = base_url.clone(); - uri.set_path(MORALIS_API_ENDPOINT); +fn construct_moralis_uri_for_nft(orig_url: &Url, address: &str, chain: &Chain) -> MmResult { + let mut uri = orig_url.clone(); uri.path_segments_mut() .map_to_mm(|_| GetNftInfoError::Internal("Invalid URI".to_string()))? + .push(MORALIS_API) + .push(MORALIS_ENDPOINT_V) .push(address) .push("nft"); uri.query_pairs_mut() @@ -1569,24 +1560,6 @@ fn construct_moralis_uri_for_nft(base_url: &Url, address: &str, chain: &Chain) - Ok(uri) } -#[derive(Clone, Serialize)] -struct MoralisPayload { - uri: Url, - signed_message: KomodefiProxyAuthValidation, -} - -#[derive(Debug, Display, EnumFromStringify)] -enum MoralisPayloadErr { - #[from_stringify("serde_json::Error")] - #[display(fmt = "Internal: {}", _0)] - Internal(String), -} - -#[inline(always)] -fn moralis_payload_str(uri: Url, signed_message: KomodefiProxyAuthValidation) -> MmResult { - Ok(serde_json::to_string(&MoralisPayload { uri, signed_message })?) -} - /// A wrapper struct for holding the chain identifier, original URL field from RPC, anti-spam URL and signed message. struct UrlSignWrapper<'a> { chain: &'a Chain, @@ -1596,18 +1569,10 @@ struct UrlSignWrapper<'a> { } async fn build_and_send_request( - uri: &Url, - original_url: &Url, + uri: &str, signed_message: Option<&KomodefiProxyAuthValidation>, ) -> MmResult { - let payload = signed_message - .map(|msg| moralis_payload_str(uri.clone(), msg.clone())) - .transpose()?; - let url_to_use = if signed_message.is_some() { - original_url.as_str() - } else { - uri.as_str() - }; - let response = send_request_to_uri(url_to_use, payload.as_deref()).await?; + let payload = signed_message.map(|msg| serde_json::to_string(&msg)).transpose()?; + let response = send_request_to_uri(uri, payload.as_deref()).await?; Ok(response) } diff --git a/mm2src/coins/nft/nft_errors.rs b/mm2src/coins/nft/nft_errors.rs index 6a1741985c..12e8d326a0 100644 --- a/mm2src/coins/nft/nft_errors.rs +++ b/mm2src/coins/nft/nft_errors.rs @@ -1,4 +1,3 @@ -use super::MoralisPayloadErr; use crate::eth::v2_activation::GenerateSignedMessageError; use crate::eth::GetEthAddressError; #[cfg(target_arch = "wasm32")] @@ -27,7 +26,6 @@ pub enum GetNftInfoError { #[from_stringify("serde_json::Error")] #[display(fmt = "Invalid response: {}", _0)] InvalidResponse(String), - #[from_stringify("MoralisPayloadErr")] #[display(fmt = "Internal: {}", _0)] Internal(String), GetEthAddressError(GetEthAddressError), @@ -159,7 +157,7 @@ pub enum UpdateNftError { #[from_stringify("LockDBError")] #[display(fmt = "DB error {}", _0)] DbError(String), - #[from_stringify("regex::Error", "MyAddressError", "MoralisPayloadErr")] + #[from_stringify("regex::Error", "MyAddressError")] #[display(fmt = "Internal: {}", _0)] Internal(String), GetNftInfoError(GetNftInfoError), From a6ad6fcadf1c6e6f44e41e83b92a6374464cdc4a Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 26 May 2024 12:43:35 +0700 Subject: [PATCH 035/233] wip: refund_nft_maker_payment_v2 --- mm2src/coins/eth.rs | 6 +- mm2src/coins/eth/nft_swap_v2/mod.rs | 124 ++++++++++++++++++++++------ mm2src/coins/lp_coins.rs | 19 ++++- 3 files changed, 122 insertions(+), 27 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 03fb33b49b..155aeae607 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -6892,16 +6892,16 @@ impl MakerNftSwapOpsV2 for EthCoin { async fn refund_nft_maker_payment_v2_timelock( &self, - args: RefundPaymentArgs<'_>, + args: RefundNftMakerPaymentArgs<'_, Self>, ) -> Result { self.refund_nft_maker_payment_v2_timelock_impl(args).await } async fn refund_nft_maker_payment_v2_secret( &self, - _args: RefundMakerPaymentArgs<'_, Self>, + args: RefundMakerPaymentArgs<'_, Self>, ) -> Result { - todo!() + self.refund_nft_maker_payment_v2_secret_impl(args).await } } diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index 46ad0c175a..6f45b6dc50 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -1,6 +1,6 @@ use crate::coin_errors::{ValidatePaymentError, ValidatePaymentResult}; use ethabi::{Contract, Token}; -use ethcore_transaction::{Action, UnverifiedTransactionWrapper}; +use ethcore_transaction::Action; use ethereum_types::{Address, U256}; use futures::compat::Future01CompatExt; use mm2_err_handle::prelude::{MapToMmResult, MmError, MmResult}; @@ -15,9 +15,9 @@ use structs::{ExpectedHtlcParams, PaymentType, ValidationParams}; use super::ContractType; use crate::eth::{addr_from_raw_pubkey, decode_contract_call, gas_limit::ETH_MAX_TRADE_GAS, EthCoin, EthCoinType, - MakerPaymentStateV2, SignedEthTx, TryToAddress, ERC1155_CONTRACT, ERC721_CONTRACT, NFT_MAKER_SWAP_V2}; -use crate::{ParseCoinAssocTypes, RefundPaymentArgs, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, TransactionErr, - ValidateNftMakerPaymentArgs}; + MakerPaymentStateV2, SignedEthTx, ERC1155_CONTRACT, ERC721_CONTRACT, NFT_MAKER_SWAP_V2}; +use crate::{ParseCoinAssocTypes, RefundMakerPaymentArgs, RefundNftMakerPaymentArgs, SendNftMakerPaymentArgs, + SpendNftMakerPaymentArgs, TransactionErr, ValidateNftMakerPaymentArgs}; impl EthCoin { pub(crate) async fn send_nft_maker_payment_v2_impl( @@ -90,7 +90,7 @@ impl EthCoin { validate_from_to_and_maker_status(tx_from_rpc, maker_address, *token_address, maker_status).await?; match self.coin_type { EthCoinType::Nft { .. } => { - let (decoded, index_bytes) = get_decoded_tx_data_and_index_bytes(contract_type, &tx_from_rpc.input.0)?; + let (decoded, bytes_index) = get_decoded_tx_data_and_bytes_index(contract_type, &tx_from_rpc.input.0)?; let amount = if matches!(contract_type, &ContractType::Erc1155) { Some(args.amount.to_string()) @@ -116,7 +116,7 @@ impl EthCoin { maker_secret_hash: args.maker_secret_hash.to_vec(), time_lock: U256::from(args.time_lock), }; - decode_and_validate_htlc_params(decoded, index_bytes, htlc_params)?; + decode_and_validate_htlc_params(decoded, bytes_index, htlc_params)?; }, EthCoinType::Eth | EthCoinType::Erc20 { .. } => { return MmError::err(ValidatePaymentError::InternalError( @@ -135,9 +135,8 @@ impl EthCoin { if args.maker_secret.len() != 32 { return Err(TransactionErr::Plain(ERRL!("maker_secret must be 32 bytes"))); } - let contract_type = args.contract_type; - let (decoded, index_bytes) = try_tx_s!(get_decoded_tx_data_and_index_bytes( - contract_type, + let (decoded, bytes_index) = try_tx_s!(get_decoded_tx_data_and_bytes_index( + args.contract_type, args.maker_payment_tx.unsigned().data() )); @@ -146,7 +145,7 @@ impl EthCoin { *etomic_swap_contract, &NFT_MAKER_SWAP_V2, &decoded, - index_bytes, + bytes_index, PaymentType::MakerPayments, ) .await @@ -171,11 +170,47 @@ impl EthCoin { pub(crate) async fn refund_nft_maker_payment_v2_timelock_impl( &self, - args: RefundPaymentArgs<'_>, + args: RefundNftMakerPaymentArgs<'_, Self>, + ) -> Result { + let etomic_swap_contract = args.swap_contract_address; + let (decoded, bytes_index) = try_tx_s!(get_decoded_tx_data_and_bytes_index( + args.contract_type, + args.maker_payment_tx.unsigned().data() + )); + + let (state, htlc_params) = try_tx_s!( + self.status_and_htlc_params_from_tx_data( + *etomic_swap_contract, + &NFT_MAKER_SWAP_V2, + &decoded, + bytes_index, + PaymentType::MakerPayments, + ) + .await + ); + match self.coin_type { + EthCoinType::Nft { .. } => { + let data = + try_tx_s!(self.prepare_refund_nft_maker_payment_v2_timelock(&args, decoded, htlc_params, state)); + self.sign_and_send_transaction( + 0.into(), + Action::Call(*etomic_swap_contract), + data, + U256::from(ETH_MAX_TRADE_GAS), // TODO: fix to a more accurate const or estimated value + ) + .compat() + .await + }, + EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported( + "ETH and ERC20 Protocols are not supported for NFT Swaps".to_string(), + )), + } + } + + pub(crate) async fn refund_nft_maker_payment_v2_secret_impl( + &self, + _args: RefundMakerPaymentArgs<'_, Self>, ) -> Result { - let _etomic_swap_contract = try_tx_s!(args.swap_contract_address.try_to_address()); - let tx: UnverifiedTransactionWrapper = try_tx_s!(rlp::decode(args.payment_tx)); - let _payment = try_tx_s!(SignedEthTx::new(tx)); todo!() } @@ -268,11 +303,6 @@ impl EthCoin { htlc_params: Vec, state: U256, ) -> Result, PrepareTxDataError> { - let spend_func = match args.contract_type { - ContractType::Erc1155 => NFT_MAKER_SWAP_V2.function("spendErc1155MakerPayment")?, - ContractType::Erc721 => NFT_MAKER_SWAP_V2.function("spendErc721MakerPayment")?, - }; - if state != U256::from(MakerPaymentStateV2::PaymentSent as u8) { return Err(PrepareTxDataError::Internal(ERRL!( "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", @@ -281,9 +311,14 @@ impl EthCoin { ))); } + let spend_func = match args.contract_type { + ContractType::Erc1155 => NFT_MAKER_SWAP_V2.function("spendErc1155MakerPayment")?, + ContractType::Erc721 => NFT_MAKER_SWAP_V2.function("spendErc721MakerPayment")?, + }; + let input_tokens = match args.contract_type { ContractType::Erc1155 => vec![ - htlc_params[0].clone(), // swap_id + htlc_params[0].clone(), // swapId Token::Address(args.maker_payment_tx.sender()), Token::FixedBytes(args.taker_secret_hash.to_vec()), Token::FixedBytes(args.maker_secret.to_vec()), @@ -305,6 +340,49 @@ impl EthCoin { Ok(data) } + fn prepare_refund_nft_maker_payment_v2_timelock( + &self, + args: &RefundNftMakerPaymentArgs<'_, Self>, + decoded: Vec, + htlc_params: Vec, + state: U256, + ) -> Result, PrepareTxDataError> { + if state != U256::from(MakerPaymentStateV2::PaymentSent as u8) { + return Err(PrepareTxDataError::Internal(ERRL!( + "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", + args.maker_payment_tx, + state + ))); + } + + let refund_func = match args.contract_type { + ContractType::Erc1155 => NFT_MAKER_SWAP_V2.function("refundErc1155MakerPaymentTimelock")?, + ContractType::Erc721 => NFT_MAKER_SWAP_V2.function("refundErc721MakerPaymentTimelock")?, + }; + + let input_tokens = match args.contract_type { + ContractType::Erc1155 => vec![ + htlc_params[0].clone(), // swapId + htlc_params[1].clone(), // taker address + Token::FixedBytes(args.taker_secret_hash.to_vec()), + Token::FixedBytes(args.maker_secret_hash.to_vec()), + htlc_params[2].clone(), // tokenAddress + decoded[2].clone(), // tokenId + decoded[3].clone(), // amount + ], + ContractType::Erc721 => vec![ + htlc_params[0].clone(), // swapId + htlc_params[1].clone(), // taker address + Token::FixedBytes(args.taker_secret_hash.to_vec()), + Token::FixedBytes(args.maker_secret_hash.to_vec()), + htlc_params[2].clone(), // tokenAddress + decoded[2].clone(), // tokenId + ], + }; + let data = refund_func.encode_input(&input_tokens)?; + Ok(data) + } + async fn status_and_htlc_params_from_tx_data( &self, swap_address: Address, @@ -501,16 +579,16 @@ async fn validate_from_to_and_maker_status( /// Identifies the correct "safeTransferFrom" function based on the contract type (either ERC1155 or ERC721) /// and decodes the provided contract call bytes using the ABI of the identified function. Additionally, it returns /// the index position of the "bytes" field within the function's parameters. -pub(crate) fn get_decoded_tx_data_and_index_bytes( +pub(crate) fn get_decoded_tx_data_and_bytes_index( contract_type: &ContractType, contract_call_bytes: &[u8], ) -> Result<(Vec, usize), PrepareTxDataError> { - let (send_func, index_bytes) = match contract_type { + let (send_func, bytes_index) = match contract_type { ContractType::Erc1155 => (ERC1155_CONTRACT.function("safeTransferFrom")?, 4), ContractType::Erc721 => (erc721_transfer_with_data()?, 3), }; let decoded = decode_contract_call(send_func, contract_call_bytes)?; - Ok((decoded, index_bytes)) + Ok((decoded, bytes_index)) } /// ERC721 contract has overloaded versions of the `safeTransferFrom` function, diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index c675c5e957..a7efece423 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1609,6 +1609,23 @@ pub struct RefundMakerPaymentArgs<'a, Coin: ParseCoinAssocTypes + ?Sized> { pub swap_unique_data: &'a [u8], } +pub struct RefundNftMakerPaymentArgs<'a, Coin: ParseCoinAssocTypes + ParseNftAssocTypes + ?Sized> { + /// Maker payment tx + pub maker_payment_tx: &'a Coin::Tx, + /// Maker will be able to refund the payment after this timestamp + pub time_lock: u64, + /// The hash of the secret generated by taker, this is used for immediate refund + pub taker_secret_hash: &'a [u8], + /// The hash of the secret generated by maker, taker needs it to spend the payment + pub maker_secret_hash: &'a [u8], + /// Unique data of specific swap + pub swap_unique_data: &'a [u8], + /// The type of smart contract that governs this NFT + pub contract_type: &'a Coin::ContractType, + /// Etomic swap contract address + pub swap_contract_address: &'a Coin::ContractAddress, +} + pub struct SpendMakerPaymentArgs<'a, Coin: ParseCoinAssocTypes + ?Sized> { /// Maker payment tx pub maker_payment_tx: &'a Coin::Tx, @@ -1691,7 +1708,7 @@ pub trait MakerNftSwapOpsV2: ParseCoinAssocTypes + ParseNftAssocTypes + Send + S /// Refund NFT maker payment transaction using timelock path async fn refund_nft_maker_payment_v2_timelock( &self, - args: RefundPaymentArgs<'_>, + args: RefundNftMakerPaymentArgs<'_, Self>, ) -> Result; /// Refund NFT maker payment transaction using immediate refund path From 5daf72391dd9b39984effbbfdc5c65234e11ac7e Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 27 May 2024 16:20:37 +0700 Subject: [PATCH 036/233] wip: refund_nft_maker_payment_v2_secret --- mm2src/coins/eth.rs | 6 +- mm2src/coins/eth/nft_swap_v2/mod.rs | 85 +++++++++++++++++-- mm2src/coins/lp_coins.rs | 10 +-- .../tests/docker_tests/eth_docker_tests.rs | 2 - 4 files changed, 88 insertions(+), 15 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 155aeae607..8495b1dd28 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -48,8 +48,8 @@ use crate::rpc_command::{account_balance, get_new_address, init_account_balance, init_scan_for_new_addresses}; use crate::{coin_balance, scan_for_new_addresses_impl, BalanceResult, CoinWithDerivationMethod, DerivationMethod, DexFee, Eip1559Ops, MakerNftSwapOpsV2, ParseCoinAssocTypes, ParseNftAssocTypes, PayForGasParams, - PrivKeyPolicy, RefundMakerPaymentArgs, RpcCommonOps, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, - ToBytes, ValidateNftMakerPaymentArgs, ValidateWatcherSpendInput, WatcherSpendType}; + PrivKeyPolicy, RpcCommonOps, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, ToBytes, + ValidateNftMakerPaymentArgs, ValidateWatcherSpendInput, WatcherSpendType}; use async_trait::async_trait; use bitcrypto::{dhash160, keccak256, ripemd160, sha256}; use common::custom_futures::repeatable::{Ready, Retry, RetryOnError}; @@ -6899,7 +6899,7 @@ impl MakerNftSwapOpsV2 for EthCoin { async fn refund_nft_maker_payment_v2_secret( &self, - args: RefundMakerPaymentArgs<'_, Self>, + args: RefundNftMakerPaymentArgs<'_, Self>, ) -> Result { self.refund_nft_maker_payment_v2_secret_impl(args).await } diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index 6f45b6dc50..fc4adbb283 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -16,8 +16,8 @@ use structs::{ExpectedHtlcParams, PaymentType, ValidationParams}; use super::ContractType; use crate::eth::{addr_from_raw_pubkey, decode_contract_call, gas_limit::ETH_MAX_TRADE_GAS, EthCoin, EthCoinType, MakerPaymentStateV2, SignedEthTx, ERC1155_CONTRACT, ERC721_CONTRACT, NFT_MAKER_SWAP_V2}; -use crate::{ParseCoinAssocTypes, RefundMakerPaymentArgs, RefundNftMakerPaymentArgs, SendNftMakerPaymentArgs, - SpendNftMakerPaymentArgs, TransactionErr, ValidateNftMakerPaymentArgs}; +use crate::{ParseCoinAssocTypes, RefundNftMakerPaymentArgs, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, + TransactionErr, ValidateNftMakerPaymentArgs}; impl EthCoin { pub(crate) async fn send_nft_maker_payment_v2_impl( @@ -209,9 +209,41 @@ impl EthCoin { pub(crate) async fn refund_nft_maker_payment_v2_secret_impl( &self, - _args: RefundMakerPaymentArgs<'_, Self>, + args: RefundNftMakerPaymentArgs<'_, Self>, ) -> Result { - todo!() + let etomic_swap_contract = args.swap_contract_address; + let (decoded, bytes_index) = try_tx_s!(get_decoded_tx_data_and_bytes_index( + args.contract_type, + args.maker_payment_tx.unsigned().data() + )); + + let (state, htlc_params) = try_tx_s!( + self.status_and_htlc_params_from_tx_data( + *etomic_swap_contract, + &NFT_MAKER_SWAP_V2, + &decoded, + bytes_index, + PaymentType::MakerPayments, + ) + .await + ); + match self.coin_type { + EthCoinType::Nft { .. } => { + let data = + try_tx_s!(self.prepare_refund_nft_maker_payment_v2_secret(&args, decoded, htlc_params, state)); + self.sign_and_send_transaction( + 0.into(), + Action::Call(*etomic_swap_contract), + data, + U256::from(ETH_MAX_TRADE_GAS), // TODO: fix to a more accurate const or estimated value + ) + .compat() + .await + }, + EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported( + "ETH and ERC20 Protocols are not supported for NFT Swaps".to_string(), + )), + } } async fn prepare_nft_maker_payment_v2_data( @@ -363,7 +395,7 @@ impl EthCoin { let input_tokens = match args.contract_type { ContractType::Erc1155 => vec![ htlc_params[0].clone(), // swapId - htlc_params[1].clone(), // taker address + htlc_params[1].clone(), // takerAddress Token::FixedBytes(args.taker_secret_hash.to_vec()), Token::FixedBytes(args.maker_secret_hash.to_vec()), htlc_params[2].clone(), // tokenAddress @@ -383,6 +415,49 @@ impl EthCoin { Ok(data) } + fn prepare_refund_nft_maker_payment_v2_secret( + &self, + args: &RefundNftMakerPaymentArgs<'_, Self>, + decoded: Vec, + htlc_params: Vec, + state: U256, + ) -> Result, PrepareTxDataError> { + if state != U256::from(MakerPaymentStateV2::PaymentSent as u8) { + return Err(PrepareTxDataError::Internal(ERRL!( + "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", + args.maker_payment_tx, + state + ))); + } + + let refund_func = match args.contract_type { + ContractType::Erc1155 => NFT_MAKER_SWAP_V2.function("refundErc1155MakerPaymentSecret")?, + ContractType::Erc721 => NFT_MAKER_SWAP_V2.function("refundErc721MakerPaymentSecret")?, + }; + + let input_tokens = match args.contract_type { + ContractType::Erc1155 => vec![ + htlc_params[0].clone(), // swapId + htlc_params[1].clone(), // takerAddress + Token::FixedBytes(args.taker_secret.to_vec()), + Token::FixedBytes(args.maker_secret_hash.to_vec()), + htlc_params[2].clone(), // tokenAddress + decoded[2].clone(), // tokenId + decoded[3].clone(), // amount + ], + ContractType::Erc721 => vec![ + htlc_params[0].clone(), // swapId + htlc_params[1].clone(), // takerAddress + Token::FixedBytes(args.taker_secret.to_vec()), + Token::FixedBytes(args.maker_secret_hash.to_vec()), + htlc_params[2].clone(), // tokenAddress + decoded[2].clone(), // tokenId + ], + }; + let data = refund_func.encode_input(&input_tokens)?; + Ok(data) + } + async fn status_and_htlc_params_from_tx_data( &self, swap_address: Address, diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index a7efece423..3f147b8ac2 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1609,15 +1609,17 @@ pub struct RefundMakerPaymentArgs<'a, Coin: ParseCoinAssocTypes + ?Sized> { pub swap_unique_data: &'a [u8], } +/// Commont refund NFT Maker Payment structure for [MakerNftSwapOpsV2::refund_nft_maker_payment_v2_timelock] and +/// [MakerNftSwapOpsV2::refund_nft_maker_payment_v2_secret] methods pub struct RefundNftMakerPaymentArgs<'a, Coin: ParseCoinAssocTypes + ParseNftAssocTypes + ?Sized> { /// Maker payment tx pub maker_payment_tx: &'a Coin::Tx, - /// Maker will be able to refund the payment after this timestamp - pub time_lock: u64, /// The hash of the secret generated by taker, this is used for immediate refund pub taker_secret_hash: &'a [u8], /// The hash of the secret generated by maker, taker needs it to spend the payment pub maker_secret_hash: &'a [u8], + /// Taker's secret + pub taker_secret: &'a [u8], /// Unique data of specific swap pub swap_unique_data: &'a [u8], /// The type of smart contract that governs this NFT @@ -1646,8 +1648,6 @@ pub struct SpendMakerPaymentArgs<'a, Coin: ParseCoinAssocTypes + ?Sized> { pub struct SpendNftMakerPaymentArgs<'a, Coin: ParseCoinAssocTypes + ParseNftAssocTypes + ?Sized> { /// Maker payment tx pub maker_payment_tx: &'a Coin::Tx, - /// Maker will be able to refund the payment after this timestamp - pub time_lock: u64, /// The hash of the secret generated by taker, this is used for immediate refund pub taker_secret_hash: &'a [u8], /// The hash of the secret generated by maker, taker needs it to spend the payment @@ -1714,7 +1714,7 @@ pub trait MakerNftSwapOpsV2: ParseCoinAssocTypes + ParseNftAssocTypes + Send + S /// Refund NFT maker payment transaction using immediate refund path async fn refund_nft_maker_payment_v2_secret( &self, - args: RefundMakerPaymentArgs<'_, Self>, + args: RefundNftMakerPaymentArgs<'_, Self>, ) -> Result; } diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index d250a708b5..5f7cd1d848 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -966,7 +966,6 @@ fn send_and_spend_erc721_maker_payment() { let spend_payment_args = SpendNftMakerPaymentArgs { maker_payment_tx: &maker_payment, - time_lock, taker_secret_hash: &[0; 32], maker_secret_hash: &maker_secret_hash, maker_secret, @@ -1082,7 +1081,6 @@ fn send_and_spend_erc1155_maker_payment() { let spend_payment_args = SpendNftMakerPaymentArgs { maker_payment_tx: &maker_payment, - time_lock, taker_secret_hash: &[0; 32], maker_secret_hash: &maker_secret_hash, maker_secret, From 2daec7a43e2c85f66ee0dbca69e7244bd3247f28 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 27 May 2024 18:23:39 +0700 Subject: [PATCH 037/233] test send_send_and_refund_erc721_maker_payment_timelock ignoring ERC1155 --- .../tests/docker_tests/eth_docker_tests.rs | 95 ++++++++++++++++++- 1 file changed, 92 insertions(+), 3 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 5f7cd1d848..a9a9bf50c0 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -10,9 +10,10 @@ use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_reque use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, ConfirmPaymentInput, DerivationMethod, Eip1559Ops, FoundSwapTxSpend, MakerNftSwapOpsV2, MarketCoinOps, MmCoinEnum, MmCoinStruct, NftSwapInfo, - ParseCoinAssocTypes, PrivKeyBuildPolicy, RefundPaymentArgs, SearchForSwapTxSpendInput, - SendNftMakerPaymentArgs, SendPaymentArgs, SpendNftMakerPaymentArgs, SpendPaymentArgs, SwapOps, - SwapTxFeePolicy, SwapTxTypeWithSecretHash, ToBytes, Transaction, ValidateNftMakerPaymentArgs}; + ParseCoinAssocTypes, PrivKeyBuildPolicy, RefundNftMakerPaymentArgs, RefundPaymentArgs, + SearchForSwapTxSpendInput, SendNftMakerPaymentArgs, SendPaymentArgs, SpendNftMakerPaymentArgs, + SpendPaymentArgs, SwapOps, SwapTxFeePolicy, SwapTxTypeWithSecretHash, ToBytes, Transaction, + ValidateNftMakerPaymentArgs}; use common::{block_on, now_sec}; use crypto::Secp256k1Secret; use ethcore_transaction::Action; @@ -902,6 +903,7 @@ fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option = SendNftMakerPaymentArgs { + time_lock: time_lock_to_refund, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + amount: 1.into(), + taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), + swap_unique_data: &[], + nft_swap_info: &nft_swap_info, + }; + let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); + log!( + "Maker sent ERC721 NFT payment, tx hash: {:02x}", + maker_payment_to_refund.tx_hash() + ); + + let confirm_input = ConfirmPaymentInput { + payment_tx: maker_payment_to_refund.tx_hex(), + confirmations: 1, + requires_nota: false, + wait_until: now_sec() + 200, + check_every: 1, + }; + maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + + wait_pending_transactions(maker_address); + + let refund_timelock_args = RefundNftMakerPaymentArgs { + maker_payment_tx: &maker_payment_to_refund, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + taker_secret, + swap_unique_data: &[], + contract_type: &ContractType::Erc721, + swap_contract_address: &sepolia_etomic_maker_nft(), + }; + let refund_timelock_tx = + block_on(taker_global_nft.refund_nft_maker_payment_v2_timelock(refund_timelock_args)).unwrap(); + log!( + "Maker refunded ERC721 NFT Maker payment Timelock, tx hash: {:02x}", + refund_timelock_tx.tx_hash() + ); + let confirm_input = ConfirmPaymentInput { + payment_tx: refund_timelock_tx.tx_hex(), + confirmations: 1, + requires_nota: false, + wait_until: now_sec() + 200, + check_every: 1, + }; + maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + + let current_owner = erc712_owner(U256::from(1)); + assert_eq!(current_owner, maker_address); +} From 6992931367c045f291fdc49a61f3cdc62655c2f2 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 27 May 2024 20:22:25 +0700 Subject: [PATCH 038/233] log info in send_send_and_refund_erc721_maker_payment_timelock --- mm2src/coins/eth/nft_swap_v2/mod.rs | 6 +- .../tests/docker_tests/eth_docker_tests.rs | 69 ++++++++++--------- 2 files changed, 42 insertions(+), 33 deletions(-) diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index fc4adbb283..c8114dc5b7 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -404,13 +404,17 @@ impl EthCoin { ], ContractType::Erc721 => vec![ htlc_params[0].clone(), // swapId - htlc_params[1].clone(), // taker address + htlc_params[1].clone(), // takerAddress Token::FixedBytes(args.taker_secret_hash.to_vec()), Token::FixedBytes(args.maker_secret_hash.to_vec()), htlc_params[2].clone(), // tokenAddress decoded[2].clone(), // tokenId ], }; + println!("htlc_params: {:?}", htlc_params); + println!("args.taker_secret_hash: {:?}", args.taker_secret_hash); + println!("args.maker_secret_hash: {:?}", args.maker_secret_hash); + println!("decoded: {:?}", decoded); let data = refund_func.encode_input(&input_tokens)?; Ok(data) } diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index a9a9bf50c0..3dfa92acdf 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1176,7 +1176,8 @@ fn test_nonce_lock() { #[test] fn send_send_and_refund_erc721_maker_payment_timelock() { - let erc721_nft = TestNftType::Erc721 { token_id: 2 }; + let token_id = 1u32; + let erc721_nft = TestNftType::Erc721 { token_id }; let maker_global_nft = get_or_create_nft(&MM_CTX, SEPOLIA_MAKER_PRIV, Some(erc721_nft)); let taker_global_nft = get_or_create_nft(&MM_CTX1, SEPOLIA_TAKER_PRIV, None); @@ -1184,46 +1185,50 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { let maker_address = block_on(maker_global_nft.my_addr()); wait_pending_transactions(maker_address); - let time_lock_to_refund = now_sec() + 1002; - let taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); + let _time_lock_to_refund = now_sec() + 1002; + let _taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); let maker_secret = &[1; 32]; let maker_secret_hash = sha256(maker_secret).to_vec(); let taker_secret = &[2; 32]; let taker_secret_hash = sha256(taker_secret).to_vec(); - let nft_swap_info = NftSwapInfo { - token_address: &sepolia_erc721(), - token_id: &BigUint::from(1u32).to_bytes(), - contract_type: &ContractType::Erc721, - swap_contract_address: &sepolia_etomic_maker_nft(), - }; + // let nft_swap_info = NftSwapInfo { + // token_address: &sepolia_erc721(), + // token_id: &BigUint::from(1u32).to_bytes(), + // contract_type: &ContractType::Erc721, + // swap_contract_address: &sepolia_etomic_maker_nft(), + // }; + // + // let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { + // time_lock: time_lock_to_refund, + // taker_secret_hash: &taker_secret_hash, + // maker_secret_hash: &maker_secret_hash, + // amount: 1.into(), + // taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), + // swap_unique_data: &[], + // nft_swap_info: &nft_swap_info, + // }; + // let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); + // log!( + // "Maker sent ERC721 NFT payment, tx hash: {:02x}", + // maker_payment_to_refund.tx_hash() + // ); + // + // let confirm_input = ConfirmPaymentInput { + // payment_tx: maker_payment_to_refund.tx_hex(), + // confirmations: 1, + // requires_nota: false, + // wait_until: now_sec() + 200, + // check_every: 1, + // }; + // maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { - time_lock: time_lock_to_refund, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - amount: 1.into(), - taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), - swap_unique_data: &[], - nft_swap_info: &nft_swap_info, - }; - let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); - log!( - "Maker sent ERC721 NFT payment, tx hash: {:02x}", - maker_payment_to_refund.tx_hash() - ); + wait_pending_transactions(maker_address); - let confirm_input = ConfirmPaymentInput { - payment_tx: maker_payment_to_refund.tx_hex(), - confirmations: 1, - requires_nota: false, - wait_until: now_sec() + 200, - check_every: 1, - }; - maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + let hex_str = "0xf901cf4385103960cbdc830249f094bac1c9f2087f39caaa4e93412c6412809186870e80b90164b88d4fde000000000000000000000000e9f3aaeb5a90f230a4ce78be737bb6d678f9baac0000000000000000000000009eb88cd58605d8fb9b14652d6152727f7e95fb4d0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0e060332b2911d1b86445fbafee823aaad2cdf2ecfa989631754586572fb9618000000000000000000000000016e281a9f2e7581269a13e516aa79d6a4a1cd980000000000000000000000000bac1c9f2087f39caaa4e93412c6412809186870e75877bb41d393b5fb8455ce60ecd8dda001d06316496b14dfa7f895656eeca4a72cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f01536379300000000000000000000000000000000000000000000000000000000665475c58401546d71a0e7785226b26d55a378e40d0f9311d6f08e9fea99a076a86142cb18bb2fd5f5f8a004de5bd129f3552c184df0bbd779d00515d3a4b6fface767be78a64d542f2f0d"; - wait_pending_transactions(maker_address); + let maker_payment_to_refund = maker_global_nft.parse_tx(hex_str.as_bytes()).unwrap(); let refund_timelock_args = RefundNftMakerPaymentArgs { maker_payment_tx: &maker_payment_to_refund, From 3f07f1fcc94c36d23c6d24b32b6c0ac59f11a8c3 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 27 May 2024 20:49:02 +0700 Subject: [PATCH 039/233] log token_id=2 send_send_and_refund_erc721_maker_payment_timelock --- .../tests/docker_tests/eth_docker_tests.rs | 69 +++++++++---------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 3dfa92acdf..b48b83b8de 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1176,7 +1176,7 @@ fn test_nonce_lock() { #[test] fn send_send_and_refund_erc721_maker_payment_timelock() { - let token_id = 1u32; + let token_id = 2u32; let erc721_nft = TestNftType::Erc721 { token_id }; let maker_global_nft = get_or_create_nft(&MM_CTX, SEPOLIA_MAKER_PRIV, Some(erc721_nft)); @@ -1185,50 +1185,47 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { let maker_address = block_on(maker_global_nft.my_addr()); wait_pending_transactions(maker_address); - let _time_lock_to_refund = now_sec() + 1002; - let _taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); + let time_lock_to_refund = now_sec() + 1002; + log!("time_lock_to_refund: {}", time_lock_to_refund); + let taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); let maker_secret = &[1; 32]; let maker_secret_hash = sha256(maker_secret).to_vec(); let taker_secret = &[2; 32]; let taker_secret_hash = sha256(taker_secret).to_vec(); - // let nft_swap_info = NftSwapInfo { - // token_address: &sepolia_erc721(), - // token_id: &BigUint::from(1u32).to_bytes(), - // contract_type: &ContractType::Erc721, - // swap_contract_address: &sepolia_etomic_maker_nft(), - // }; - // - // let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { - // time_lock: time_lock_to_refund, - // taker_secret_hash: &taker_secret_hash, - // maker_secret_hash: &maker_secret_hash, - // amount: 1.into(), - // taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), - // swap_unique_data: &[], - // nft_swap_info: &nft_swap_info, - // }; - // let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); - // log!( - // "Maker sent ERC721 NFT payment, tx hash: {:02x}", - // maker_payment_to_refund.tx_hash() - // ); - // - // let confirm_input = ConfirmPaymentInput { - // payment_tx: maker_payment_to_refund.tx_hex(), - // confirmations: 1, - // requires_nota: false, - // wait_until: now_sec() + 200, - // check_every: 1, - // }; - // maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + let nft_swap_info = NftSwapInfo { + token_address: &sepolia_erc721(), + token_id: &BigUint::from(token_id).to_bytes(), + contract_type: &ContractType::Erc721, + swap_contract_address: &sepolia_etomic_maker_nft(), + }; - wait_pending_transactions(maker_address); + let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { + time_lock: time_lock_to_refund, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + amount: 1.into(), + taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), + swap_unique_data: &[], + nft_swap_info: &nft_swap_info, + }; + let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); + log!( + "Maker sent ERC721 NFT payment, tx hash: {:02x}", + maker_payment_to_refund.tx_hash() + ); - let hex_str = "0xf901cf4385103960cbdc830249f094bac1c9f2087f39caaa4e93412c6412809186870e80b90164b88d4fde000000000000000000000000e9f3aaeb5a90f230a4ce78be737bb6d678f9baac0000000000000000000000009eb88cd58605d8fb9b14652d6152727f7e95fb4d0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0e060332b2911d1b86445fbafee823aaad2cdf2ecfa989631754586572fb9618000000000000000000000000016e281a9f2e7581269a13e516aa79d6a4a1cd980000000000000000000000000bac1c9f2087f39caaa4e93412c6412809186870e75877bb41d393b5fb8455ce60ecd8dda001d06316496b14dfa7f895656eeca4a72cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f01536379300000000000000000000000000000000000000000000000000000000665475c58401546d71a0e7785226b26d55a378e40d0f9311d6f08e9fea99a076a86142cb18bb2fd5f5f8a004de5bd129f3552c184df0bbd779d00515d3a4b6fface767be78a64d542f2f0d"; + let confirm_input = ConfirmPaymentInput { + payment_tx: maker_payment_to_refund.tx_hex(), + confirmations: 1, + requires_nota: false, + wait_until: now_sec() + 200, + check_every: 1, + }; + maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - let maker_payment_to_refund = maker_global_nft.parse_tx(hex_str.as_bytes()).unwrap(); + wait_pending_transactions(maker_address); let refund_timelock_args = RefundNftMakerPaymentArgs { maker_payment_tx: &maker_payment_to_refund, From 0079362ec447ef8840bf10f54a756ce930e4c6ae Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 28 May 2024 11:44:37 +0700 Subject: [PATCH 040/233] test only refund_nft_maker_payment_v2_timelock --- mm2src/coins/eth/nft_swap_v2/mod.rs | 16 +++ .../tests/docker_tests/eth_docker_tests.rs | 107 +++++++++++++----- 2 files changed, 92 insertions(+), 31 deletions(-) diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index c8114dc5b7..085eb00ea7 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -31,10 +31,12 @@ impl EthCoin { args.nft_swap_info.contract_type )); let htlc_data = try_tx_s!(self.prepare_htlc_data(&args)); + println!("encoded htlc_data to send payment: {:?}", htlc_data); match &self.coin_type { EthCoinType::Nft { .. } => { let data = try_tx_s!(self.prepare_nft_maker_payment_v2_data(&args, htlc_data).await); + println!("encoded tx send payment data: {:?}", data); self.sign_and_send_transaction( 0.into(), Action::Call(*args.nft_swap_info.token_address), @@ -312,6 +314,20 @@ impl EthCoin { .call_request(self.my_addr().await, swap_address, None, Some(data.into())) .await?; let decoded_tokens = function.decode_output(&bytes.0)?; + + println!( + "decoded makerPayments paymentHash: {:?}", + decoded_tokens.get(0).unwrap() + ); + println!( + "decoded makerPayments paymentLockTime: {:?}", + decoded_tokens.get(1).unwrap() + ); + println!( + "decoded makerPayments MakerPaymentState: {:?}", + decoded_tokens.get(2).unwrap() + ); + let state = decoded_tokens .get(2) .ok_or_else(|| PaymentStatusErr::Internal(ERRL!("Payment status must contain 'state' as the 2nd token")))?; diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index b48b83b8de..94f18a2ab9 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1183,49 +1183,63 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { let taker_global_nft = get_or_create_nft(&MM_CTX1, SEPOLIA_TAKER_PRIV, None); let maker_address = block_on(maker_global_nft.my_addr()); + let taker_address = block_on(taker_global_nft.my_addr()); wait_pending_transactions(maker_address); - let time_lock_to_refund = now_sec() + 1002; + let time_lock_to_refund = now_sec() - 1000; log!("time_lock_to_refund: {}", time_lock_to_refund); - let taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); + let _taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); let maker_secret = &[1; 32]; let maker_secret_hash = sha256(maker_secret).to_vec(); let taker_secret = &[2; 32]; let taker_secret_hash = sha256(taker_secret).to_vec(); - let nft_swap_info = NftSwapInfo { - token_address: &sepolia_erc721(), - token_id: &BigUint::from(token_id).to_bytes(), - contract_type: &ContractType::Erc721, - swap_contract_address: &sepolia_etomic_maker_nft(), - }; + // let nft_swap_info = NftSwapInfo { + // token_address: &sepolia_erc721(), + // token_id: &BigUint::from(token_id).to_bytes(), + // contract_type: &ContractType::Erc721, + // swap_contract_address: &sepolia_etomic_maker_nft(), + // }; + // + // let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { + // time_lock: time_lock_to_refund, + // taker_secret_hash: &taker_secret_hash, + // maker_secret_hash: &maker_secret_hash, + // amount: 1.into(), + // taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), + // swap_unique_data: &[], + // nft_swap_info: &nft_swap_info, + // }; + // let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); + // log!( + // "Maker sent ERC721 NFT payment, tx hash: {:02x}", + // maker_payment_to_refund.tx_hash() + // ); + // + // let confirm_input = ConfirmPaymentInput { + // payment_tx: maker_payment_to_refund.tx_hex(), + // confirmations: 1, + // requires_nota: false, + // wait_until: now_sec() + 200, + // check_every: 1, + // }; + // maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { - time_lock: time_lock_to_refund, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - amount: 1.into(), - taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), - swap_unique_data: &[], - nft_swap_info: &nft_swap_info, - }; - let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); - log!( - "Maker sent ERC721 NFT payment, tx hash: {:02x}", - maker_payment_to_refund.tx_hash() - ); + wait_pending_transactions(maker_address); - let confirm_input = ConfirmPaymentInput { - payment_tx: maker_payment_to_refund.tx_hex(), - confirmations: 1, - requires_nota: false, - wait_until: now_sec() + 200, - check_every: 1, - }; - maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + let raw_tx_hex = "f9012e7785103a6708f8830249f0949eb88cd58605d8fb9b14652d6152727f7e95fb4d80b8c40f235fce0367f2f8f78bb4d8f2b6267e20ef7b5467e183315546049e2a88443230bd0b3100000000000000000000000016e281a9f2e7581269a13e516aa79d6a4a1cd98075877bb41d393b5fb8455ce60ecd8dda001d06316496b14dfa7f895656eeca4a72cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000000000000000000000000bac1c9f2087f39caaa4e93412c6412809186870e00000000000000000000000000000000000000000000000000000000000000028401546d71a0cf6e0876226c1cec668423b59eebe2bb22bbfc8f1d39914633d2555ff7bcbd8ca016f46356ad917fb268a0386946cc66b868339d593db3060f60bcb1262d2b4f9a"; + let maker_payment_to_refund = maker_global_nft.parse_tx(raw_tx_hex.as_bytes()).unwrap(); - wait_pending_transactions(maker_address); + let payment_hash_refund = calculate_payment_hash( + &taker_address, + &maker_address, + &taker_secret_hash, + &maker_secret_hash, + &sepolia_erc721(), + token_id, + ); + println!("payment_hash_refund: {:?}", payment_hash_refund); let refund_timelock_args = RefundNftMakerPaymentArgs { maker_payment_tx: &maker_payment_to_refund, @@ -1254,3 +1268,34 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { let current_owner = erc712_owner(U256::from(1)); assert_eq!(current_owner, maker_address); } + +// test function +fn calculate_payment_hash( + taker: &Address, + sender: &Address, + taker_secret_hash: &[u8], + maker_secret_hash: &[u8], + token_address: &Address, + token_id: u32, +) -> [u8; 20] { + use bitcrypto::ripemd160; + // Convert token_id to a 256-bit representation as Solidity does with abi.encodePacked + let token_id_bytes = { + let mut buf = [0u8; 32]; + buf[24..32].copy_from_slice(&token_id.to_be_bytes()); + buf + }; + + // Encode the data as Solidity would do with abi.encodePacked + let mut encoded = Vec::new(); + encoded.extend_from_slice(taker.as_bytes()); + encoded.extend_from_slice(sender.as_bytes()); + encoded.extend_from_slice(taker_secret_hash); + encoded.extend_from_slice(maker_secret_hash); + encoded.extend_from_slice(token_address.as_bytes()); + encoded.extend_from_slice(&token_id_bytes); + + // Hash with RIPEMD160 + let payment_hash = ripemd160(&encoded); + *payment_hash +} From 0c164fb14ff75c81e5d726d450c6d1ab9f400d17 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 28 May 2024 12:08:59 +0700 Subject: [PATCH 041/233] test only refund_nft_maker_payment_v2_timelock --- .../tests/docker_tests/eth_docker_tests.rs | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 94f18a2ab9..8d8ebf1ffe 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1176,7 +1176,7 @@ fn test_nonce_lock() { #[test] fn send_send_and_refund_erc721_maker_payment_timelock() { - let token_id = 2u32; + let token_id = 3u32; let erc721_nft = TestNftType::Erc721 { token_id }; let maker_global_nft = get_or_create_nft(&MM_CTX, SEPOLIA_MAKER_PRIV, Some(erc721_nft)); @@ -1188,48 +1188,48 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { let time_lock_to_refund = now_sec() - 1000; log!("time_lock_to_refund: {}", time_lock_to_refund); - let _taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); + let taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); let maker_secret = &[1; 32]; let maker_secret_hash = sha256(maker_secret).to_vec(); let taker_secret = &[2; 32]; let taker_secret_hash = sha256(taker_secret).to_vec(); - // let nft_swap_info = NftSwapInfo { - // token_address: &sepolia_erc721(), - // token_id: &BigUint::from(token_id).to_bytes(), - // contract_type: &ContractType::Erc721, - // swap_contract_address: &sepolia_etomic_maker_nft(), - // }; - // - // let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { - // time_lock: time_lock_to_refund, - // taker_secret_hash: &taker_secret_hash, - // maker_secret_hash: &maker_secret_hash, - // amount: 1.into(), - // taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), - // swap_unique_data: &[], - // nft_swap_info: &nft_swap_info, - // }; - // let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); - // log!( - // "Maker sent ERC721 NFT payment, tx hash: {:02x}", - // maker_payment_to_refund.tx_hash() - // ); - // - // let confirm_input = ConfirmPaymentInput { - // payment_tx: maker_payment_to_refund.tx_hex(), - // confirmations: 1, - // requires_nota: false, - // wait_until: now_sec() + 200, - // check_every: 1, - // }; - // maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + let nft_swap_info = NftSwapInfo { + token_address: &sepolia_erc721(), + token_id: &BigUint::from(token_id).to_bytes(), + contract_type: &ContractType::Erc721, + swap_contract_address: &sepolia_etomic_maker_nft(), + }; + + let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { + time_lock: time_lock_to_refund, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + amount: 1.into(), + taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), + swap_unique_data: &[], + nft_swap_info: &nft_swap_info, + }; + let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); + log!( + "Maker sent ERC721 NFT payment, tx hash: {:02x}", + maker_payment_to_refund.tx_hash() + ); + + let confirm_input = ConfirmPaymentInput { + payment_tx: maker_payment_to_refund.tx_hex(), + confirmations: 1, + requires_nota: false, + wait_until: now_sec() + 200, + check_every: 1, + }; + maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); wait_pending_transactions(maker_address); - let raw_tx_hex = "f9012e7785103a6708f8830249f0949eb88cd58605d8fb9b14652d6152727f7e95fb4d80b8c40f235fce0367f2f8f78bb4d8f2b6267e20ef7b5467e183315546049e2a88443230bd0b3100000000000000000000000016e281a9f2e7581269a13e516aa79d6a4a1cd98075877bb41d393b5fb8455ce60ecd8dda001d06316496b14dfa7f895656eeca4a72cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000000000000000000000000bac1c9f2087f39caaa4e93412c6412809186870e00000000000000000000000000000000000000000000000000000000000000028401546d71a0cf6e0876226c1cec668423b59eebe2bb22bbfc8f1d39914633d2555ff7bcbd8ca016f46356ad917fb268a0386946cc66b868339d593db3060f60bcb1262d2b4f9a"; - let maker_payment_to_refund = maker_global_nft.parse_tx(raw_tx_hex.as_bytes()).unwrap(); + // let raw_tx_hex = "f9012e7785103a6708f8830249f0949eb88cd58605d8fb9b14652d6152727f7e95fb4d80b8c40f235fce0367f2f8f78bb4d8f2b6267e20ef7b5467e183315546049e2a88443230bd0b3100000000000000000000000016e281a9f2e7581269a13e516aa79d6a4a1cd98075877bb41d393b5fb8455ce60ecd8dda001d06316496b14dfa7f895656eeca4a72cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000000000000000000000000bac1c9f2087f39caaa4e93412c6412809186870e00000000000000000000000000000000000000000000000000000000000000028401546d71a0cf6e0876226c1cec668423b59eebe2bb22bbfc8f1d39914633d2555ff7bcbd8ca016f46356ad917fb268a0386946cc66b868339d593db3060f60bcb1262d2b4f9a"; + // let maker_payment_to_refund = maker_global_nft.parse_tx(raw_tx_hex.as_bytes()).unwrap(); let payment_hash_refund = calculate_payment_hash( &taker_address, From 63af2bcaed6e2c40a073ab0db08403447b97b60a Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 28 May 2024 16:07:40 +0700 Subject: [PATCH 042/233] use global_nft_with_random_privkey in send_send_and_refund_erc721_maker_payment_timelock --- .../tests/docker_tests/docker_tests_common.rs | 2 +- .../tests/docker_tests/eth_docker_tests.rs | 19 ++++++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 751ca88db9..a4506f1c11 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -132,7 +132,7 @@ pub const WATCHERS_SWAP_CONTRACT_BYTES: &str = "608060405234801561000f575f80fd5b pub const ERC721_TEST_TOKEN_BYTES: &str = "608060405234801562000010575f80fd5b50604051620022ac380380620022ac8339818101604052810190620000369190620001ea565b8181815f9081620000489190620004a4565b5080600190816200005a9190620004a4565b505050505062000588565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c6826200007e565b810181811067ffffffffffffffff82111715620000e857620000e76200008e565b5b80604052505050565b5f620000fc62000065565b90506200010a8282620000bb565b919050565b5f67ffffffffffffffff8211156200012c576200012b6200008e565b5b62000137826200007e565b9050602081019050919050565b5f5b838110156200016357808201518184015260208101905062000146565b5f8484015250505050565b5f620001846200017e846200010f565b620000f1565b905082815260208101848484011115620001a357620001a26200007a565b5b620001b084828562000144565b509392505050565b5f82601f830112620001cf57620001ce62000076565b5b8151620001e18482602086016200016e565b91505092915050565b5f80604083850312156200020357620002026200006e565b5b5f83015167ffffffffffffffff81111562000223576200022262000072565b5b6200023185828601620001b8565b925050602083015167ffffffffffffffff81111562000255576200025462000072565b5b6200026385828601620001b8565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620002bc57607f821691505b602082108103620002d257620002d162000277565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002f9565b620003428683620002f9565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200038c6200038662000380846200035a565b62000363565b6200035a565b9050919050565b5f819050919050565b620003a7836200036c565b620003bf620003b68262000393565b84845462000305565b825550505050565b5f90565b620003d5620003c7565b620003e28184846200039c565b505050565b5b818110156200040957620003fd5f82620003cb565b600181019050620003e8565b5050565b601f82111562000458576200042281620002d8565b6200042d84620002ea565b810160208510156200043d578190505b620004556200044c85620002ea565b830182620003e7565b50505b505050565b5f82821c905092915050565b5f6200047a5f19846008026200045d565b1980831691505092915050565b5f62000494838362000469565b9150826002028217905092915050565b620004af826200026d565b67ffffffffffffffff811115620004cb57620004ca6200008e565b5b620004d78254620002a4565b620004e48282856200040d565b5f60209050601f8311600181146200051a575f841562000505578287015190505b62000511858262000487565b86555062000580565b601f1984166200052a86620002d8565b5f5b8281101562000553578489015182556001820191506020850194506020810190506200052c565b868310156200057357848901516200056f601f89168262000469565b8355505b6001600288020188555050505b505050505050565b611d1680620005965f395ff3fe608060405234801561000f575f80fd5b50600436106100e8575f3560e01c80636352211e1161008a578063a22cb46511610064578063a22cb46514610258578063b88d4fde14610274578063c87b56dd14610290578063e985e9c5146102c0576100e8565b80636352211e146101da57806370a082311461020a57806395d89b411461023a576100e8565b8063095ea7b3116100c6578063095ea7b31461016a57806323b872dd1461018657806340c10f19146101a257806342842e0e146101be576100e8565b806301ffc9a7146100ec57806306fdde031461011c578063081812fc1461013a575b5f80fd5b610106600480360381019061010191906115a7565b6102f0565b60405161011391906115ec565b60405180910390f35b6101246103d1565b604051610131919061168f565b60405180910390f35b610154600480360381019061014f91906116e2565b610460565b604051610161919061174c565b60405180910390f35b610184600480360381019061017f919061178f565b61047b565b005b6101a0600480360381019061019b91906117cd565b610491565b005b6101bc60048036038101906101b7919061178f565b610590565b005b6101d860048036038101906101d391906117cd565b61059e565b005b6101f460048036038101906101ef91906116e2565b6105bd565b604051610201919061174c565b60405180910390f35b610224600480360381019061021f919061181d565b6105ce565b6040516102319190611857565b60405180910390f35b610242610684565b60405161024f919061168f565b60405180910390f35b610272600480360381019061026d919061189a565b610714565b005b61028e60048036038101906102899190611a04565b61072a565b005b6102aa60048036038101906102a591906116e2565b610747565b6040516102b7919061168f565b60405180910390f35b6102da60048036038101906102d59190611a84565b6107ad565b6040516102e791906115ec565b60405180910390f35b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103ba57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103ca57506103c98261083b565b5b9050919050565b60605f80546103df90611aef565b80601f016020809104026020016040519081016040528092919081815260200182805461040b90611aef565b80156104565780601f1061042d57610100808354040283529160200191610456565b820191905f5260205f20905b81548152906001019060200180831161043957829003601f168201915b5050505050905090565b5f61046a826108a4565b506104748261092a565b9050919050565b61048d8282610488610963565b61096a565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610501575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016104f8919061174c565b60405180910390fd5b5f610514838361050f610963565b61097c565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461058a578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161058193929190611b1f565b60405180910390fd5b50505050565b61059a8282610b87565b5050565b6105b883838360405180602001604052805f81525061072a565b505050565b5f6105c7826108a4565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361063f575f6040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401610636919061174c565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b60606001805461069390611aef565b80601f01602080910402602001604051908101604052809291908181526020018280546106bf90611aef565b801561070a5780601f106106e15761010080835404028352916020019161070a565b820191905f5260205f20905b8154815290600101906020018083116106ed57829003601f168201915b5050505050905090565b61072661071f610963565b8383610c7a565b5050565b610735848484610491565b61074184848484610de3565b50505050565b6060610752826108a4565b505f61075c610f95565b90505f81511161077a5760405180602001604052805f8152506107a5565b8061078484610fab565b604051602001610795929190611b8e565b6040516020818303038152906040525b915050919050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f806108af83611075565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361092157826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016109189190611857565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b61097783838360016110ae565b505050565b5f8061098784611075565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146109c8576109c781848661126d565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a5357610a075f855f806110ae565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610ad257600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610bf7575f6040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610bee919061174c565b60405180910390fd5b5f610c0383835f61097c565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c75575f6040517f73c6ac6e000000000000000000000000000000000000000000000000000000008152600401610c6c919061174c565b60405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610cea57816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401610ce1919061174c565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610dd691906115ec565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b1115610f8f578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02610e26610963565b8685856040518563ffffffff1660e01b8152600401610e489493929190611c03565b6020604051808303815f875af1925050508015610e8357506040513d601f19601f82011682018060405250810190610e809190611c61565b60015b610f04573d805f8114610eb1576040519150601f19603f3d011682016040523d82523d5f602084013e610eb6565b606091505b505f815103610efc57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610ef3919061174c565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614610f8d57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610f84919061174c565b60405180910390fd5b505b50505050565b606060405180602001604052805f815250905090565b60605f6001610fb984611330565b0190505f8167ffffffffffffffff811115610fd757610fd66118e0565b5b6040519080825280601f01601f1916602001820160405280156110095781602001600182028036833780820191505090505b5090505f82602001820190505b60011561106a578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161105f5761105e611c8c565b5b0494505f8503611016575b819350505050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b80806110e657505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611218575f6110f5846108a4565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561115f57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611172575061117081846107ad565b155b156111b457826040517fa9fbf51f0000000000000000000000000000000000000000000000000000000081526004016111ab919061174c565b60405180910390fd5b811561121657838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b611278838383611481565b61132b575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036112ec57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016112e39190611857565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401611322929190611cb9565b60405180910390fd5b505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061138c577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161138257611381611c8c565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106113c9576d04ee2d6d415b85acef810000000083816113bf576113be611c8c565b5b0492506020810190505b662386f26fc1000083106113f857662386f26fc1000083816113ee576113ed611c8c565b5b0492506010810190505b6305f5e1008310611421576305f5e100838161141757611416611c8c565b5b0492506008810190505b612710831061144657612710838161143c5761143b611c8c565b5b0492506004810190505b60648310611469576064838161145f5761145e611c8c565b5b0492506002810190505b600a8310611478576001810190505b80915050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561153857508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806114f957506114f884846107ad565b5b8061153757508273ffffffffffffffffffffffffffffffffffffffff1661151f8361092a565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61158681611552565b8114611590575f80fd5b50565b5f813590506115a18161157d565b92915050565b5f602082840312156115bc576115bb61154a565b5b5f6115c984828501611593565b91505092915050565b5f8115159050919050565b6115e6816115d2565b82525050565b5f6020820190506115ff5f8301846115dd565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561163c578082015181840152602081019050611621565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61166182611605565b61166b818561160f565b935061167b81856020860161161f565b61168481611647565b840191505092915050565b5f6020820190508181035f8301526116a78184611657565b905092915050565b5f819050919050565b6116c1816116af565b81146116cb575f80fd5b50565b5f813590506116dc816116b8565b92915050565b5f602082840312156116f7576116f661154a565b5b5f611704848285016116ce565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6117368261170d565b9050919050565b6117468161172c565b82525050565b5f60208201905061175f5f83018461173d565b92915050565b61176e8161172c565b8114611778575f80fd5b50565b5f8135905061178981611765565b92915050565b5f80604083850312156117a5576117a461154a565b5b5f6117b28582860161177b565b92505060206117c3858286016116ce565b9150509250929050565b5f805f606084860312156117e4576117e361154a565b5b5f6117f18682870161177b565b93505060206118028682870161177b565b9250506040611813868287016116ce565b9150509250925092565b5f602082840312156118325761183161154a565b5b5f61183f8482850161177b565b91505092915050565b611851816116af565b82525050565b5f60208201905061186a5f830184611848565b92915050565b611879816115d2565b8114611883575f80fd5b50565b5f8135905061189481611870565b92915050565b5f80604083850312156118b0576118af61154a565b5b5f6118bd8582860161177b565b92505060206118ce85828601611886565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61191682611647565b810181811067ffffffffffffffff82111715611935576119346118e0565b5b80604052505050565b5f611947611541565b9050611953828261190d565b919050565b5f67ffffffffffffffff821115611972576119716118e0565b5b61197b82611647565b9050602081019050919050565b828183375f83830152505050565b5f6119a86119a384611958565b61193e565b9050828152602081018484840111156119c4576119c36118dc565b5b6119cf848285611988565b509392505050565b5f82601f8301126119eb576119ea6118d8565b5b81356119fb848260208601611996565b91505092915050565b5f805f8060808587031215611a1c57611a1b61154a565b5b5f611a298782880161177b565b9450506020611a3a8782880161177b565b9350506040611a4b878288016116ce565b925050606085013567ffffffffffffffff811115611a6c57611a6b61154e565b5b611a78878288016119d7565b91505092959194509250565b5f8060408385031215611a9a57611a9961154a565b5b5f611aa78582860161177b565b9250506020611ab88582860161177b565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611b0657607f821691505b602082108103611b1957611b18611ac2565b5b50919050565b5f606082019050611b325f83018661173d565b611b3f6020830185611848565b611b4c604083018461173d565b949350505050565b5f81905092915050565b5f611b6882611605565b611b728185611b54565b9350611b8281856020860161161f565b80840191505092915050565b5f611b998285611b5e565b9150611ba58284611b5e565b91508190509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f611bd582611bb1565b611bdf8185611bbb565b9350611bef81856020860161161f565b611bf881611647565b840191505092915050565b5f608082019050611c165f83018761173d565b611c23602083018661173d565b611c306040830185611848565b8181036060830152611c428184611bcb565b905095945050505050565b5f81519050611c5b8161157d565b92915050565b5f60208284031215611c7657611c7561154a565b5b5f611c8384828501611c4d565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f604082019050611ccc5f83018561173d565b611cd96020830184611848565b939250505056fea26469706673582212207439b47c2a9a1624955997732075917bbf1da26949d000c778f561eb5687576164736f6c63430008180033"; pub const ERC1155_TEST_TOKEN_BYTES: &str = "608060405234801562000010575f80fd5b50604051620024eb380380620024eb8339818101604052810190620000369190620001ea565b8062000048816200005060201b60201c565b505062000554565b806002908162000061919062000470565b5050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c6826200007e565b810181811067ffffffffffffffff82111715620000e857620000e76200008e565b5b80604052505050565b5f620000fc62000065565b90506200010a8282620000bb565b919050565b5f67ffffffffffffffff8211156200012c576200012b6200008e565b5b62000137826200007e565b9050602081019050919050565b5f5b838110156200016357808201518184015260208101905062000146565b5f8484015250505050565b5f620001846200017e846200010f565b620000f1565b905082815260208101848484011115620001a357620001a26200007a565b5b620001b084828562000144565b509392505050565b5f82601f830112620001cf57620001ce62000076565b5b8151620001e18482602086016200016e565b91505092915050565b5f602082840312156200020257620002016200006e565b5b5f82015167ffffffffffffffff81111562000222576200022162000072565b5b6200023084828501620001b8565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200028857607f821691505b6020821081036200029e576200029d62000243565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002c5565b6200030e8683620002c5565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f62000358620003526200034c8462000326565b6200032f565b62000326565b9050919050565b5f819050919050565b620003738362000338565b6200038b62000382826200035f565b848454620002d1565b825550505050565b5f90565b620003a162000393565b620003ae81848462000368565b505050565b5b81811015620003d557620003c95f8262000397565b600181019050620003b4565b5050565b601f8211156200042457620003ee81620002a4565b620003f984620002b6565b8101602085101562000409578190505b620004216200041885620002b6565b830182620003b3565b50505b505050565b5f82821c905092915050565b5f620004465f198460080262000429565b1980831691505092915050565b5f62000460838362000435565b9150826002028217905092915050565b6200047b8262000239565b67ffffffffffffffff8111156200049757620004966200008e565b5b620004a3825462000270565b620004b0828285620003d9565b5f60209050601f831160018114620004e6575f8415620004d1578287015190505b620004dd858262000453565b8655506200054c565b601f198416620004f686620002a4565b5f5b828110156200051f57848901518255600182019150602085019450602081019050620004f8565b868310156200053f57848901516200053b601f89168262000435565b8355505b6001600288020188555050505b505050505050565b611f8980620005625f395ff3fe608060405234801561000f575f80fd5b5060043610610090575f3560e01c80634e1273f4116100645780634e1273f414610140578063731133e914610170578063a22cb4651461018c578063e985e9c5146101a8578063f242432a146101d857610090565b8062fdd58e1461009457806301ffc9a7146100c45780630e89341c146100f45780632eb2c2d614610124575b5f80fd5b6100ae60048036038101906100a991906113bd565b6101f4565b6040516100bb919061140a565b60405180910390f35b6100de60048036038101906100d99190611478565b610249565b6040516100eb91906114bd565b60405180910390f35b61010e600480360381019061010991906114d6565b61032a565b60405161011b919061158b565b60405180910390f35b61013e6004803603810190610139919061179b565b6103bc565b005b61015a60048036038101906101559190611926565b610463565b6040516101679190611a53565b60405180910390f35b61018a60048036038101906101859190611a73565b61056a565b005b6101a660048036038101906101a19190611b1d565b61057c565b005b6101c260048036038101906101bd9190611b5b565b610592565b6040516101cf91906114bd565b60405180910390f35b6101f260048036038101906101ed9190611b99565b610620565b005b5f805f8381526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f7fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061031357507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103235750610322826106c7565b5b9050919050565b60606002805461033990611c59565b80601f016020809104026020016040519081016040528092919081815260200182805461036590611c59565b80156103b05780601f10610387576101008083540402835291602001916103b0565b820191905f5260205f20905b81548152906001019060200180831161039357829003601f168201915b50505050509050919050565b5f6103c5610730565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561040a57506104088682610592565b155b1561044e5780866040517fe237d922000000000000000000000000000000000000000000000000000000008152600401610445929190611c98565b60405180910390fd5b61045b8686868686610737565b505050505050565b606081518351146104af57815183516040517f5b0599910000000000000000000000000000000000000000000000000000000081526004016104a6929190611cbf565b60405180910390fd5b5f835167ffffffffffffffff8111156104cb576104ca6115af565b5b6040519080825280602002602001820160405280156104f95781602001602082028036833780820191505090505b5090505f5b845181101561055f5761053561051d828761082b90919063ffffffff16565b610530838761083e90919063ffffffff16565b6101f4565b82828151811061054857610547611ce6565b5b6020026020010181815250508060010190506104fe565b508091505092915050565b61057684848484610851565b50505050565b61058e610587610730565b83836108e6565b5050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f610629610730565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561066e575061066c8682610592565b155b156106b25780866040517fe237d9220000000000000000000000000000000000000000000000000000000081526004016106a9929190611c98565b60405180910390fd5b6106bf8686868686610a4f565b505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036107a7575f6040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161079e9190611d13565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610817575f6040517f01a8351400000000000000000000000000000000000000000000000000000000815260040161080e9190611d13565b60405180910390fd5b6108248585858585610b55565b5050505050565b5f60208202602084010151905092915050565b5f60208202602084010151905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036108c1575f6040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016108b89190611d13565b60405180910390fd5b5f806108cd8585610c01565b915091506108de5f87848487610b55565b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610956575f6040517fced3e10000000000000000000000000000000000000000000000000000000000815260040161094d9190611d13565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610a4291906114bd565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610abf575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401610ab69190611d13565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610b2f575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401610b269190611d13565b60405180910390fd5b5f80610b3b8585610c01565b91509150610b4c8787848487610b55565b50505050505050565b610b6185858585610c31565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610bfa575f610b9d610730565b90506001845103610be9575f610bbc5f8661083e90919063ffffffff16565b90505f610bd25f8661083e90919063ffffffff16565b9050610be2838989858589610fc1565b5050610bf8565b610bf7818787878787611170565b5b505b5050505050565b60608060405191506001825283602083015260408201905060018152826020820152604081016040529250929050565b8051825114610c7b57815181516040517f5b059991000000000000000000000000000000000000000000000000000000008152600401610c72929190611cbf565b60405180910390fd5b5f610c84610730565b90505f5b8351811015610e80575f610ca5828661083e90919063ffffffff16565b90505f610cbb838661083e90919063ffffffff16565b90505f73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614610dde575f805f8481526020019081526020015f205f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015610d8a57888183856040517f03dee4c5000000000000000000000000000000000000000000000000000000008152600401610d819493929190611d2c565b60405180910390fd5b8181035f808581526020019081526020015f205f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610e7357805f808481526020019081526020015f205f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610e6b9190611d9c565b925050819055505b5050806001019050610c88565b506001835103610f3b575f610e9e5f8561083e90919063ffffffff16565b90505f610eb45f8561083e90919063ffffffff16565b90508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051610f2c929190611cbf565b60405180910390a45050610fba565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051610fb1929190611dcf565b60405180910390a45b5050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115611168578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b8152600401611021959493929190611e56565b6020604051808303815f875af192505050801561105c57506040513d601f19601f820116820180604052508101906110599190611ec2565b60015b6110dd573d805f811461108a576040519150601f19603f3d011682016040523d82523d5f602084013e61108f565b606091505b505f8151036110d557846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016110cc9190611d13565b60405180910390fd5b805181602001fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461116657846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161115d9190611d13565b60405180910390fd5b505b505050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115611317578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b81526004016111d0959493929190611eed565b6020604051808303815f875af192505050801561120b57506040513d601f19601f820116820180604052508101906112089190611ec2565b60015b61128c573d805f8114611239576040519150601f19603f3d011682016040523d82523d5f602084013e61123e565b606091505b505f81510361128457846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161127b9190611d13565b60405180910390fd5b805181602001fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461131557846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161130c9190611d13565b60405180910390fd5b505b505050505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61135982611330565b9050919050565b6113698161134f565b8114611373575f80fd5b50565b5f8135905061138481611360565b92915050565b5f819050919050565b61139c8161138a565b81146113a6575f80fd5b50565b5f813590506113b781611393565b92915050565b5f80604083850312156113d3576113d2611328565b5b5f6113e085828601611376565b92505060206113f1858286016113a9565b9150509250929050565b6114048161138a565b82525050565b5f60208201905061141d5f8301846113fb565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61145781611423565b8114611461575f80fd5b50565b5f813590506114728161144e565b92915050565b5f6020828403121561148d5761148c611328565b5b5f61149a84828501611464565b91505092915050565b5f8115159050919050565b6114b7816114a3565b82525050565b5f6020820190506114d05f8301846114ae565b92915050565b5f602082840312156114eb576114ea611328565b5b5f6114f8848285016113a9565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561153857808201518184015260208101905061151d565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61155d82611501565b611567818561150b565b935061157781856020860161151b565b61158081611543565b840191505092915050565b5f6020820190508181035f8301526115a38184611553565b905092915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6115e582611543565b810181811067ffffffffffffffff82111715611604576116036115af565b5b80604052505050565b5f61161661131f565b905061162282826115dc565b919050565b5f67ffffffffffffffff821115611641576116406115af565b5b602082029050602081019050919050565b5f80fd5b5f61166861166384611627565b61160d565b9050808382526020820190506020840283018581111561168b5761168a611652565b5b835b818110156116b457806116a088826113a9565b84526020840193505060208101905061168d565b5050509392505050565b5f82601f8301126116d2576116d16115ab565b5b81356116e2848260208601611656565b91505092915050565b5f80fd5b5f67ffffffffffffffff821115611709576117086115af565b5b61171282611543565b9050602081019050919050565b828183375f83830152505050565b5f61173f61173a846116ef565b61160d565b90508281526020810184848401111561175b5761175a6116eb565b5b61176684828561171f565b509392505050565b5f82601f830112611782576117816115ab565b5b813561179284826020860161172d565b91505092915050565b5f805f805f60a086880312156117b4576117b3611328565b5b5f6117c188828901611376565b95505060206117d288828901611376565b945050604086013567ffffffffffffffff8111156117f3576117f261132c565b5b6117ff888289016116be565b935050606086013567ffffffffffffffff8111156118205761181f61132c565b5b61182c888289016116be565b925050608086013567ffffffffffffffff81111561184d5761184c61132c565b5b6118598882890161176e565b9150509295509295909350565b5f67ffffffffffffffff8211156118805761187f6115af565b5b602082029050602081019050919050565b5f6118a361189e84611866565b61160d565b905080838252602082019050602084028301858111156118c6576118c5611652565b5b835b818110156118ef57806118db8882611376565b8452602084019350506020810190506118c8565b5050509392505050565b5f82601f83011261190d5761190c6115ab565b5b813561191d848260208601611891565b91505092915050565b5f806040838503121561193c5761193b611328565b5b5f83013567ffffffffffffffff8111156119595761195861132c565b5b611965858286016118f9565b925050602083013567ffffffffffffffff8111156119865761198561132c565b5b611992858286016116be565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6119ce8161138a565b82525050565b5f6119df83836119c5565b60208301905092915050565b5f602082019050919050565b5f611a018261199c565b611a0b81856119a6565b9350611a16836119b6565b805f5b83811015611a46578151611a2d88826119d4565b9750611a38836119eb565b925050600181019050611a19565b5085935050505092915050565b5f6020820190508181035f830152611a6b81846119f7565b905092915050565b5f805f8060808587031215611a8b57611a8a611328565b5b5f611a9887828801611376565b9450506020611aa9878288016113a9565b9350506040611aba878288016113a9565b925050606085013567ffffffffffffffff811115611adb57611ada61132c565b5b611ae78782880161176e565b91505092959194509250565b611afc816114a3565b8114611b06575f80fd5b50565b5f81359050611b1781611af3565b92915050565b5f8060408385031215611b3357611b32611328565b5b5f611b4085828601611376565b9250506020611b5185828601611b09565b9150509250929050565b5f8060408385031215611b7157611b70611328565b5b5f611b7e85828601611376565b9250506020611b8f85828601611376565b9150509250929050565b5f805f805f60a08688031215611bb257611bb1611328565b5b5f611bbf88828901611376565b9550506020611bd088828901611376565b9450506040611be1888289016113a9565b9350506060611bf2888289016113a9565b925050608086013567ffffffffffffffff811115611c1357611c1261132c565b5b611c1f8882890161176e565b9150509295509295909350565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611c7057607f821691505b602082108103611c8357611c82611c2c565b5b50919050565b611c928161134f565b82525050565b5f604082019050611cab5f830185611c89565b611cb86020830184611c89565b9392505050565b5f604082019050611cd25f8301856113fb565b611cdf60208301846113fb565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f602082019050611d265f830184611c89565b92915050565b5f608082019050611d3f5f830187611c89565b611d4c60208301866113fb565b611d5960408301856113fb565b611d6660608301846113fb565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611da68261138a565b9150611db18361138a565b9250828201905080821115611dc957611dc8611d6f565b5b92915050565b5f6040820190508181035f830152611de781856119f7565b90508181036020830152611dfb81846119f7565b90509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f611e2882611e04565b611e328185611e0e565b9350611e4281856020860161151b565b611e4b81611543565b840191505092915050565b5f60a082019050611e695f830188611c89565b611e766020830187611c89565b611e8360408301866113fb565b611e9060608301856113fb565b8181036080830152611ea28184611e1e565b90509695505050505050565b5f81519050611ebc8161144e565b92915050565b5f60208284031215611ed757611ed6611328565b5b5f611ee484828501611eae565b91505092915050565b5f60a082019050611f005f830188611c89565b611f0d6020830187611c89565b8181036040830152611f1f81866119f7565b90508181036060830152611f3381856119f7565b90508181036080830152611f478184611e1e565b9050969550505050505056fea26469706673582212203835581c6344b12728c44fa4d9e912cd60e64012c1b772bb703d1c36825c16fd64736f6c63430008180033"; pub const NFT_SWAP_CONTRACT_BYTES: &str = "60a060405234801562000010575f80fd5b50604051620055a2380380620055a2833981810160405281019062000036919062000147565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200009e90620001fb565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506200021b565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200011182620000e6565b9050919050565b620001238162000105565b81146200012e575f80fd5b50565b5f81519050620001418162000118565b92915050565b5f602082840312156200015f576200015e620000e2565b5b5f6200016e8482850162000131565b91505092915050565b5f82825260208201905092915050565b7f66656541646472657373206d757374206e6f74206265207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f620001e360238362000177565b9150620001f08262000187565b604082019050919050565b5f6020820190508181035f8301526200021481620001d5565b9050919050565b608051615360620002425f395f8181612aef01528181612b8a0152612f4801526153605ff3fe608060405260043610610113575f3560e01c80639b4603f21161009f578063cc90c19911610063578063cc90c1991461038e578063d6a71eb4146103b6578063e06cf966146103de578063efccb9eb14610408578063f23a6e611461044657610113565b80639b4603f2146102be578063b27e46fb146102da578063bc197c8114610302578063c8d9009b1461033e578063c92cd12d1461036657610113565b8063150b7a02116100e6578063150b7a02146101cb5780633e6af5f21461020757806346b95ac71461022f57806365e266171461026e5780636e6bf6d21461029657610113565b806301ffc9a71461011757806305ec158d146101535780630f235fce1461017b578063146e5b24146101a3575b5f80fd5b348015610122575f80fd5b5061013d6004803603810190610138919061386f565b610482565b60405161014a91906138b4565b60405180910390f35b34801561015e575f80fd5b506101796004803603810190610174919061398d565b610563565b005b348015610186575f80fd5b506101a1600480360381019061019c9190613a2a565b610823565b005b3480156101ae575f80fd5b506101c960048036038101906101c49190613ab3565b610add565b005b3480156101d6575f80fd5b506101f160048036038101906101ec9190613bb1565b610cc3565b6040516101fe9190613c44565b60405180910390f35b348015610212575f80fd5b5061022d60048036038101906102289190613ab3565b611112565b005b34801561023a575f80fd5b5061025560048036038101906102509190613c5d565b611423565b6040516102659493929190613d53565b60405180910390f35b348015610279575f80fd5b50610294600480360381019061028f9190613ab3565b611485565b005b3480156102a1575f80fd5b506102bc60048036038101906102b79190613a2a565b6118e9565b005b6102d860048036038101906102d39190613dc0565b611ba4565b005b3480156102e5575f80fd5b5061030060048036038101906102fb919061398d565b611eda565b005b34801561030d575f80fd5b5061032860048036038101906103239190613eb2565b612199565b6040516103359190613c44565b60405180910390f35b348015610349575f80fd5b50610364600480360381019061035f9190613a2a565b6121d5565b005b348015610371575f80fd5b5061038c6004803603810190610387919061398d565b6124fe565b005b348015610399575f80fd5b506103b460048036038101906103af9190613ab3565b61282c565b005b3480156103c1575f80fd5b506103dc60048036038101906103d79190613f89565b612bdc565b005b3480156103e9575f80fd5b506103f2612f46565b6040516103ff919061405c565b60405180910390f35b348015610413575f80fd5b5061042e60048036038101906104299190613c5d565b612f6a565b60405161043d939291906140bb565b60405180910390f35b348015610451575f80fd5b5061046c600480360381019061046791906140f0565b612fb6565b6040516104799190613c44565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061054c57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061055c575061055b8261344a565b5b9050919050565b6001600381111561057757610576613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff1660038111156105a9576105a8613ce0565b5b146105e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e090614206565b60405180910390fd5b5f600387336002896040516020016106019190614244565b60405160208183030381529060405260405161061d91906142ca565b602060405180830381855afa158015610638573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065b91906142f4565b888888886040516020016106759796959493929190614384565b60405160208183030381529060405260405161069191906142ca565b602060405180830381855afa1580156106ac573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610736576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072d9061444e565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561076c5761076b613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd73886040516107a0919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016107eb94939291906144d6565b5f604051808303815f87803b158015610802575f80fd5b505af1158015610814573d5f803e3d5ffd5b50505050505050505050505050565b6001600381111561083757610836613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561086957610868613ce0565b5b146108a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a090614206565b60405180910390fd5b5f60038633878787876040516020016108c79695949392919061452c565b6040516020818303038152906040526040516108e391906142ca565b602060405180830381855afa1580156108fe573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097f9061444e565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156109f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ea9061460b565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610a2957610a28613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907287604051610a5d919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610aa693929190614629565b5f604051808303815f87803b158015610abd575f80fd5b505af1158015610acf573d5f803e3d5ffd5b505050505050505050505050565b60016004811115610af157610af0613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115610b2457610b23613ce0565b5b14610b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5b90614206565b60405180910390fd5b5f600387878733888888604051602001610b84979695949392919061465e565b604051602081830303815290604052604051610ba091906142ca565b602060405180830381855afa158015610bbb573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610c46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3d9061444e565b60405180910390fd5b600260015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610c7d57610c7c613ce0565b5b02179055507f9c45e43e2ef051f70491ffd5221bf02ab37e1324128714ef9610df5f24fc9fb588604051610cb1919061447b565b60405180910390a15050505050505050565b5f808383810190610cd49190614807565b90505f6003811115610ce957610ce8613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff166003811115610d1e57610d1d613ce0565b5b14610d5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d55906148a2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603610dd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc79061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610e42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3990614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610eb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eab90614a00565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610f22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1990614a68565b60405180910390fd5b610f2f81602001516134b3565b15610f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6690614ad0565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610f9d9695949392919061452c565b604051602081830303815290604052604051610fb991906142ca565b602060405180830381855afa158015610fd4573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561102457611023613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156110bb576110ba613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f01516040516110f5919061447b565b60405180910390a163150b7a0260e01b9250505095945050505050565b6001600481111561112657611125613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561115957611158613ce0565b5b14611199576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119090614206565b60405180910390fd5b5f6003878787336002896040516020016111b39190614244565b6040516020818303038152906040526040516111cf91906142ca565b602060405180830381855afa1580156111ea573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061120d91906142f4565b8888604051602001611225979695949392919061465e565b60405160208183030381529060405260405161124191906142ca565b602060405180830381855afa15801561125c573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146112e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112de9061444e565b60405180910390fd5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff0219169083600481111561131e5761131d613ce0565b5b02179055507f45169a52eef651b20a81474b50b8a5d83225225fcd097ef3cf7952d9ab304f278885604051611354929190614aee565b60405180910390a15f86886113699190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113e7573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156113e1573d5f803e3d5ffd5b50611418565b5f83905061141633838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b6001602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900463ffffffff1690805f01601c9054906101000a900460ff16905084565b6001600481111561149957611498613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff1660048111156114cc576114cb613ce0565b5b148061151c5750600260048111156114e7576114e6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561151a57611519613ce0565b5b145b61155b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155290614be5565b60405180910390fd5b5f60038787873388888860405160200161157b979695949392919061465e565b60405160208183030381529060405260405161159791906142ca565b602060405180830381855afa1580156115b2573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461163d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116349061444e565b60405180910390fd5b6002600481111561165157611650613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561168457611683613ce0565b5b036116f65760015f8981526020019081526020015f205f0160189054906101000a900463ffffffff1663ffffffff164210156116f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ec9061460b565b60405180910390fd5b5b6001600481111561170a57611709613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561173d5761173c613ce0565b5b036117af5760015f8981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156117ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a590614c73565b60405180910390fd5b5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156117e6576117e5613ce0565b5b02179055507fbdd7a4be6d82798a500b59077706b12d3f45acf5504828919f92501307b2b9538860405161181a919061447b565b60405180910390a15f868861182f9190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118ad573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156118a7573d5f803e3d5ffd5b506118de565b5f8390506118dc33838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b600160038111156118fd576118fc613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561192f5761192e613ce0565b5b1461196f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196690614206565b60405180910390fd5b5f600386336002886040516020016119879190614244565b6040516020818303038152906040526040516119a391906142ca565b602060405180830381855afa1580156119be573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906119e191906142f4565b8787876040516020016119f99695949392919061452c565b604051602081830303815290604052604051611a1591906142ca565b602060405180830381855afa158015611a30573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611aba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab19061444e565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115611af057611aef613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051611b24919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401611b6d93929190614629565b5f604051808303815f87803b158015611b84575f80fd5b505af1158015611b96573d5f803e3d5ffd5b505050505050505050505050565b5f6004811115611bb757611bb6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115611bea57611be9613ce0565b5b14611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2190614d01565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611c98576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8f90614d8f565b60405180910390fd5b5f3411611cda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd190614e1d565b60405180910390fd5b853411611d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1390614eab565b60405180910390fd5b5f60038734611d2b9190614ec9565b88883389895f604051602001611d47979695949392919061465e565b604051602081830303815290604052604051611d6391906142ca565b602060405180830381855afa158015611d7e573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115611dd657611dd5613ce0565b5b81525060015f8a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115611e9157611e90613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd93588604051611ec8919061447b565b60405180910390a15050505050505050565b60016003811115611eee57611eed613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115611f2057611f1f613ce0565b5b14611f60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5790614206565b60405180910390fd5b5f600387338888888888604051602001611f809796959493929190614384565b604051602081830303815290604052604051611f9c91906142ca565b602060405180830381855afa158015611fb7573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612041576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120389061444e565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156120ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a39061460b565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156120e2576120e1613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907288604051612116919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161216194939291906144d6565b5f604051808303815f87803b158015612178575f80fd5b505af115801561218a573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121cc90614f46565b60405180910390fd5b600160038111156121e9576121e8613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561221b5761221a613ce0565b5b1461225b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161225290614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c090614fae565b60405180910390fd5b5f60033387876002886040516020016122e29190614244565b6040516020818303038152906040526040516122fe91906142ca565b602060405180830381855afa158015612319573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061233c91906142f4565b87876040516020016123539695949392919061452c565b60405160208183030381529060405260405161236f91906142ca565b602060405180830381855afa15801561238a573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612414576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240b9061444e565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561244a57612449613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161247e919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016124c793929190614629565b5f604051808303815f87803b1580156124de575f80fd5b505af11580156124f0573d5f803e3d5ffd5b505050505050505050505050565b6001600381111561251257612511613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561254457612543613ce0565b5b14612584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257b90614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146125f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125e990614fae565b60405180910390fd5b5f600333888860028960405160200161260b9190614244565b60405160208183030381529060405260405161262791906142ca565b602060405180830381855afa158015612642573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061266591906142f4565b88888860405160200161267e9796959493929190614384565b60405160208183030381529060405260405161269a91906142ca565b602060405180830381855afa1580156126b5573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461273f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127369061444e565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561277557612774613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0886040516127a9919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016127f494939291906144d6565b5f604051808303815f87803b15801561280b575f80fd5b505af115801561281d573d5f803e3d5ffd5b50505050505050505050505050565b600260048111156128405761283f613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561287357612872613ce0565b5b146128b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128aa9061503c565b60405180910390fd5b5f600387873388886002896040516020016128ce9190614244565b6040516020818303038152906040526040516128ea91906142ca565b602060405180830381855afa158015612905573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061292891906142f4565b8860405160200161293f979695949392919061465e565b60405160208183030381529060405260405161295b91906142ca565b602060405180830381855afa158015612976573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612a01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129f89061444e565b60405180910390fd5b600360015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115612a3857612a37613ce0565b5b02179055507f0d0da0df275f85bed3a5fe7ae79f3559341a3f9ccd8e010133438135bda00a878884604051612a6e929190614aee565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612b56573373ffffffffffffffffffffffffffffffffffffffff166108fc8890811502906040515f60405180830381858888f19350505050158015612aec573d5f803e3d5ffd5b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f19350505050158015612b50573d5f803e3d5ffd5b50612bd2565b5f829050612b8533898373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b612bd07f0000000000000000000000000000000000000000000000000000000000000000888373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b5050505050505050565b5f6004811115612bef57612bee613ce0565b5b60015f8b81526020019081526020015f205f01601c9054906101000a900460ff166004811115612c2257612c21613ce0565b5b14612c62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c59906150ca565b60405180910390fd5b5f8811612ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c9b90615132565b60405180910390fd5b5f8711612ce6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cdd9061519a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612d54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d4b90614d8f565b60405180910390fd5b5f60038989883389898d604051602001612d74979695949392919061465e565b604051602081830303815290604052604051612d9091906142ca565b602060405180830381855afa158015612dab573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115612e0357612e02613ce0565b5b81525060015f8c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115612ebe57612ebd613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358a604051612ef5919061447b565b60405180910390a15f879050612f3933308b8d612f129190614b42565b8473ffffffffffffffffffffffffffffffffffffffff16613543909392919063ffffffff16565b5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f808383810190612fc79190614807565b90505f6003811115612fdc57612fdb613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff16600381111561301157613010613ce0565b5b14613051576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161304890615228565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff16036130c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130ba9061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161312c90614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146131a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161319e90614a00565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614613215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161320c90614a68565b60405180910390fd5b5f8511613257576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161324e90615290565b60405180910390fd5b61326481602001516134b3565b156132a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161329b90614ad0565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c6040516020016132d49796959493929190614384565b6040516020818303038152906040526040516132f091906142ca565b602060405180830381855afa15801561330b573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561335b5761335a613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156133f2576133f1613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f015160405161342c919061447b565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b61353e838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85856040516024016134f79291906152ae565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b505050565b6135bf848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161357893929190614629565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b50505050565b5f6135ef828473ffffffffffffffffffffffffffffffffffffffff1661365a90919063ffffffff16565b90505f81511415801561361357508080602001905181019061361191906152ff565b155b1561365557826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161364c919061405c565b60405180910390fd5b505050565b606061366783835f61366f565b905092915050565b6060814710156136b657306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016136ad919061405c565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516136de91906142ca565b5f6040518083038185875af1925050503d805f8114613718576040519150601f19603f3d011682016040523d82523d5f602084013e61371d565b606091505b509150915061372d868383613738565b925050509392505050565b60608261374d57613748826137c5565b6137bd565b5f825114801561377357505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156137b557836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016137ac919061405c565b60405180910390fd5b8190506137be565b5b9392505050565b5f815111156137d75780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61384e8161381a565b8114613858575f80fd5b50565b5f8135905061386981613845565b92915050565b5f6020828403121561388457613883613812565b5b5f6138918482850161385b565b91505092915050565b5f8115159050919050565b6138ae8161389a565b82525050565b5f6020820190506138c75f8301846138a5565b92915050565b5f819050919050565b6138df816138cd565b81146138e9575f80fd5b50565b5f813590506138fa816138d6565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61392982613900565b9050919050565b6139398161391f565b8114613943575f80fd5b50565b5f8135905061395481613930565b92915050565b5f819050919050565b61396c8161395a565b8114613976575f80fd5b50565b5f8135905061398781613963565b92915050565b5f805f805f805f60e0888a0312156139a8576139a7613812565b5b5f6139b58a828b016138ec565b97505060206139c68a828b01613946565b96505060406139d78a828b016138ec565b95505060606139e88a828b016138ec565b94505060806139f98a828b01613946565b93505060a0613a0a8a828b01613979565b92505060c0613a1b8a828b01613979565b91505092959891949750929550565b5f805f805f8060c08789031215613a4457613a43613812565b5b5f613a5189828a016138ec565b9650506020613a6289828a01613946565b9550506040613a7389828a016138ec565b9450506060613a8489828a016138ec565b9350506080613a9589828a01613946565b92505060a0613aa689828a01613979565b9150509295509295509295565b5f805f805f805f60e0888a031215613ace57613acd613812565b5b5f613adb8a828b016138ec565b9750506020613aec8a828b01613979565b9650506040613afd8a828b01613979565b9550506060613b0e8a828b01613946565b9450506080613b1f8a828b016138ec565b93505060a0613b308a828b016138ec565b92505060c0613b418a828b01613946565b91505092959891949750929550565b5f80fd5b5f80fd5b5f80fd5b5f8083601f840112613b7157613b70613b50565b5b8235905067ffffffffffffffff811115613b8e57613b8d613b54565b5b602083019150836001820283011115613baa57613ba9613b58565b5b9250929050565b5f805f805f60808688031215613bca57613bc9613812565b5b5f613bd788828901613946565b9550506020613be888828901613946565b9450506040613bf988828901613979565b935050606086013567ffffffffffffffff811115613c1a57613c19613816565b5b613c2688828901613b5c565b92509250509295509295909350565b613c3e8161381a565b82525050565b5f602082019050613c575f830184613c35565b92915050565b5f60208284031215613c7257613c71613812565b5b5f613c7f848285016138ec565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b613cbc81613c88565b82525050565b5f63ffffffff82169050919050565b613cda81613cc2565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60058110613d1e57613d1d613ce0565b5b50565b5f819050613d2e82613d0d565b919050565b5f613d3d82613d21565b9050919050565b613d4d81613d33565b82525050565b5f608082019050613d665f830187613cb3565b613d736020830186613cd1565b613d806040830185613cd1565b613d8d6060830184613d44565b95945050505050565b613d9f81613cc2565b8114613da9575f80fd5b50565b5f81359050613dba81613d96565b92915050565b5f805f805f805f60e0888a031215613ddb57613dda613812565b5b5f613de88a828b016138ec565b9750506020613df98a828b01613979565b9650506040613e0a8a828b01613946565b9550506060613e1b8a828b016138ec565b9450506080613e2c8a828b016138ec565b93505060a0613e3d8a828b01613dac565b92505060c0613e4e8a828b01613dac565b91505092959891949750929550565b5f8083601f840112613e7257613e71613b50565b5b8235905067ffffffffffffffff811115613e8f57613e8e613b54565b5b602083019150836020820283011115613eab57613eaa613b58565b5b9250929050565b5f805f805f805f8060a0898b031215613ece57613ecd613812565b5b5f613edb8b828c01613946565b9850506020613eec8b828c01613946565b975050604089013567ffffffffffffffff811115613f0d57613f0c613816565b5b613f198b828c01613e5d565b9650965050606089013567ffffffffffffffff811115613f3c57613f3b613816565b5b613f488b828c01613e5d565b9450945050608089013567ffffffffffffffff811115613f6b57613f6a613816565b5b613f778b828c01613b5c565b92509250509295985092959890939650565b5f805f805f805f805f6101208a8c031215613fa757613fa6613812565b5b5f613fb48c828d016138ec565b9950506020613fc58c828d01613979565b9850506040613fd68c828d01613979565b9750506060613fe78c828d01613946565b9650506080613ff88c828d01613946565b95505060a06140098c828d016138ec565b94505060c061401a8c828d016138ec565b93505060e061402b8c828d01613dac565b92505061010061403d8c828d01613dac565b9150509295985092959850929598565b6140568161391f565b82525050565b5f60208201905061406f5f83018461404d565b92915050565b6004811061408657614085613ce0565b5b50565b5f81905061409682614075565b919050565b5f6140a582614089565b9050919050565b6140b58161409b565b82525050565b5f6060820190506140ce5f830186613cb3565b6140db6020830185613cd1565b6140e860408301846140ac565b949350505050565b5f805f805f8060a0878903121561410a57614109613812565b5b5f61411789828a01613946565b965050602061412889828a01613946565b955050604061413989828a01613979565b945050606061414a89828a01613979565b935050608087013567ffffffffffffffff81111561416b5761416a613816565b5b61417789828a01613b5c565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f6141f0602a83614186565b91506141fb82614196565b604082019050919050565b5f6020820190508181035f83015261421d816141e4565b9050919050565b5f819050919050565b61423e614239826138cd565b614224565b82525050565b5f61424f828461422d565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b5f5b8381101561428f578082015181840152602081019050614274565b5f8484015250505050565b5f6142a48261425e565b6142ae8185614268565b93506142be818560208601614272565b80840191505092915050565b5f6142d5828461429a565b915081905092915050565b5f815190506142ee816138d6565b92915050565b5f6020828403121561430957614308613812565b5b5f614316848285016142e0565b91505092915050565b5f8160601b9050919050565b5f6143358261431f565b9050919050565b5f6143468261432b565b9050919050565b61435e6143598261391f565b61433c565b82525050565b5f819050919050565b61437e6143798261395a565b614364565b82525050565b5f61438f828a61434d565b60148201915061439f828961434d565b6014820191506143af828861422d565b6020820191506143bf828761422d565b6020820191506143cf828661434d565b6014820191506143df828561436d565b6020820191506143ef828461436d565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f614438601383614186565b915061444382614404565b602082019050919050565b5f6020820190508181035f8301526144658161442c565b9050919050565b614475816138cd565b82525050565b5f60208201905061448e5f83018461446c565b92915050565b61449d8161395a565b82525050565b5f82825260208201905092915050565b50565b5f6144c15f836144a3565b91506144cc826144b3565b5f82019050919050565b5f60a0820190506144e95f83018761404d565b6144f6602083018661404d565b6145036040830185614494565b6145106060830184614494565b8181036080830152614521816144b6565b905095945050505050565b5f614537828961434d565b601482019150614547828861434d565b601482019150614557828761422d565b602082019150614567828661422d565b602082019150614577828561434d565b601482019150614587828461436d565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f6145f5603883614186565b91506146008261459b565b604082019050919050565b5f6020820190508181035f830152614622816145e9565b9050919050565b5f60608201905061463c5f83018661404d565b614649602083018561404d565b6146566040830184614494565b949350505050565b5f614669828a61436d565b602082019150614679828961436d565b602082019150614689828861434d565b601482019150614699828761434d565b6014820191506146a9828661422d565b6020820191506146b9828561422d565b6020820191506146c9828461434d565b60148201915081905098975050505050505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b614728826146e2565b810181811067ffffffffffffffff82111715614747576147466146f2565b5b80604052505050565b5f614759613809565b9050614765828261471f565b919050565b5f60c0828403121561477f5761477e6146de565b5b61478960c0614750565b90505f614798848285016138ec565b5f8301525060206147ab84828501613946565b60208301525060406147bf84828501613946565b60408301525060606147d3848285016138ec565b60608301525060806147e7848285016138ec565b60808301525060a06147fb84828501613dac565b60a08301525092915050565b5f60c0828403121561481c5761481b613812565b5b5f6148298482850161476a565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f61488c602a83614186565b915061489782614832565b604082019050919050565b5f6020820190508181035f8301526148b981614880565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f6148f4601e83614186565b91506148ff826148c0565b602082019050919050565b5f6020820190508181035f830152614921816148e8565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f61495c601e83614186565b915061496782614928565b602082019050919050565b5f6020820190508181035f83015261498981614950565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f6149ea602383614186565b91506149f582614990565b604082019050919050565b5f6020820190508181035f830152614a17816149de565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f614a52601b83614186565b9150614a5d82614a1e565b602082019050919050565b5f6020820190508181035f830152614a7f81614a46565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f614aba601a83614186565b9150614ac582614a86565b602082019050919050565b5f6020820190508181035f830152614ae781614aae565b9050919050565b5f604082019050614b015f83018561446c565b614b0e602083018461446c565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614b4c8261395a565b9150614b578361395a565b9250828201905080821115614b6f57614b6e614b15565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e74206f722054616b6572417070726f7665640000000000602082015250565b5f614bcf603b83614186565b9150614bda82614b75565b604082019050919050565b5f6020820190508181035f830152614bfc81614bc3565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e74207072652d617070726f7665206c6f636b2074696d65000000602082015250565b5f614c5d603d83614186565b9150614c6882614c03565b604082019050919050565b5f6020820190508181035f830152614c8a81614c51565b9050919050565b7f54616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f614ceb602483614186565b9150614cf682614c91565b604082019050919050565b5f6020820190508181035f830152614d1881614cdf565b9050919050565b7f5265636569766572206d757374206e6f74206265207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f614d79602183614186565b9150614d8482614d1f565b604082019050919050565b5f6020820190508181035f830152614da681614d6d565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f614e07602383614186565b9150614e1282614dad565b604082019050919050565b5f6020820190508181035f830152614e3481614dfb565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e20645f8201527f6578206665650000000000000000000000000000000000000000000000000000602082015250565b5f614e95602683614186565b9150614ea082614e3b565b604082019050919050565b5f6020820190508181035f830152614ec281614e89565b9050919050565b5f614ed38261395a565b9150614ede8361395a565b9250828203905081811115614ef657614ef5614b15565b5b92915050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f614f30601d83614186565b9150614f3b82614efc565b602082019050919050565b5f6020820190508181035f830152614f5d81614f24565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f614f98601583614186565b9150614fa382614f64565b602082019050919050565b5f6020820190508181035f830152614fc581614f8c565b9050919050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520545f8201527f616b6572417070726f7665640000000000000000000000000000000000000000602082015250565b5f615026602c83614186565b915061503182614fcc565b604082019050919050565b5f6020820190508181035f8301526150538161501a565b9050919050565b7f4552433230207632207061796d656e7420697320616c726561647920696e69745f8201527f69616c697a656400000000000000000000000000000000000000000000000000602082015250565b5f6150b4602783614186565b91506150bf8261505a565b604082019050919050565b5f6020820190508181035f8301526150e1816150a8565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f61511c601783614186565b9150615127826150e8565b602082019050919050565b5f6020820190508181035f83015261514981615110565b9050919050565b7f44657820666565206d757374206e6f74206265207a65726f00000000000000005f82015250565b5f615184601883614186565b915061518f82615150565b602082019050919050565b5f6020820190508181035f8301526151b181615178565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f615212602b83614186565b915061521d826151b8565b604082019050919050565b5f6020820190508181035f83015261523f81615206565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f61527a601c83614186565b915061528582615246565b602082019050919050565b5f6020820190508181035f8301526152a78161526e565b9050919050565b5f6040820190506152c15f83018561404d565b6152ce6020830184614494565b9392505050565b6152de8161389a565b81146152e8575f80fd5b50565b5f815190506152f9816152d5565b92915050565b5f6020828403121561531457615313613812565b5b5f615321848285016152eb565b9150509291505056fea26469706673582212200d86b0f6898fb823c55626c3b02a7098bc8622606b092e0f458df6c86ce2967864736f6c63430008180033"; -pub const NFT_MAKER_SWAP_V2_BYTES: &str = "6080604052348015600e575f80fd5b50612ffd8061001c5f395ff3fe608060405234801561000f575f80fd5b50600436106100a7575f3560e01c8063b27e46fb1161006f578063b27e46fb1461015f578063bc197c811461017b578063c8d9009b146101ab578063c92cd12d146101c7578063efccb9eb146101e3578063f23a6e6114610215576100a7565b806301ffc9a7146100ab57806305ec158d146100db5780630f235fce146100f7578063150b7a02146101135780636e6bf6d214610143575b5f80fd5b6100c560048036038101906100c09190611ebc565b610245565b6040516100d29190611f01565b60405180910390f35b6100f560048036038101906100f09190611fda565b610326565b005b610111600480360381019061010c9190612077565b6105e6565b005b61012d60048036038101906101289190612161565b6108a0565b60405161013a91906121f4565b60405180910390f35b61015d60048036038101906101589190612077565b610cef565b005b61017960048036038101906101749190611fda565b610faa565b005b61019560048036038101906101909190612262565b611269565b6040516101a291906121f4565b60405180910390f35b6101c560048036038101906101c09190612077565b6112a5565b005b6101e160048036038101906101dc9190611fda565b6115ce565b005b6101fd60048036038101906101f89190612339565b6118fc565b60405161020c9392919061242f565b60405180910390f35b61022f600480360381019061022a9190612464565b611948565b60405161023c91906121f4565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061030f57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061031f575061031e82611ddc565b5b9050919050565b6001600381111561033a576103396123bc565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561036c5761036b6123bc565b5b146103ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a39061257a565b60405180910390fd5b5f600387336002896040516020016103c491906125b8565b6040516020818303038152906040526040516103e09190612624565b602060405180830381855afa1580156103fb573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061041e919061264e565b8888888860405160200161043897969594939291906126de565b6040516020818303038152906040526040516104549190612624565b602060405180830381855afa15801561046f573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146104f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f0906127a8565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561052f5761052e6123bc565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd738860405161056391906127d5565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016105ae949392919061283f565b5f604051808303815f87803b1580156105c5575f80fd5b505af11580156105d7573d5f803e3d5ffd5b50505050505050505050505050565b600160038111156105fa576105f96123bc565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561062c5761062b6123bc565b5b1461066c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106639061257a565b60405180910390fd5b5f600386338787878760405160200161068a96959493929190612895565b6040516020818303038152906040526040516106a69190612624565b602060405180830381855afa1580156106c1573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461074b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610742906127a8565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156107b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ad90612974565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff021916908360038111156107ec576107eb6123bc565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad192190728760405161082091906127d5565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b815260040161086993929190612992565b5f604051808303815f87803b158015610880575f80fd5b505af1158015610892573d5f803e3d5ffd5b505050505050505050505050565b5f8083838101906108b19190612b1a565b90505f60038111156108c6576108c56123bc565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff1660038111156108fb576108fa6123bc565b5b1461093b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093290612bb5565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff16036109ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109a490612c1d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610a1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1690612c85565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8890612d13565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610aff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af690612d7b565b60405180910390fd5b610b0c8160200151611e45565b15610b4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4390612de3565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610b7a96959493929190612895565b604051602081830303815290604052604051610b969190612624565b602060405180830381855afa158015610bb1573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115610c0157610c006123bc565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115610c9857610c976123bc565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051610cd291906127d5565b60405180910390a163150b7a0260e01b9250505095945050505050565b60016003811115610d0357610d026123bc565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff166003811115610d3557610d346123bc565b5b14610d75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6c9061257a565b60405180910390fd5b5f60038633600288604051602001610d8d91906125b8565b604051602081830303815290604052604051610da99190612624565b602060405180830381855afa158015610dc4573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610de7919061264e565b878787604051602001610dff96959493929190612895565b604051602081830303815290604052604051610e1b9190612624565b602060405180830381855afa158015610e36573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610ec0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb7906127a8565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610ef657610ef56123bc565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051610f2a91906127d5565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610f7393929190612992565b5f604051808303815f87803b158015610f8a575f80fd5b505af1158015610f9c573d5f803e3d5ffd5b505050505050505050505050565b60016003811115610fbe57610fbd6123bc565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115610ff057610fef6123bc565b5b14611030576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110279061257a565b60405180910390fd5b5f60038733888888888860405160200161105097969594939291906126de565b60405160208183030381529060405260405161106c9190612624565b602060405180830381855afa158015611087573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611111576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611108906127a8565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff1642101561117c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117390612974565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156111b2576111b16123bc565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad19219072886040516111e691906127d5565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b8152600401611231949392919061283f565b5f604051808303815f87803b158015611248575f80fd5b505af115801561125a573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129c90612e4b565b60405180910390fd5b600160038111156112b9576112b86123bc565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff1660038111156112eb576112ea6123bc565b5b1461132b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113229061257a565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139090612eb3565b60405180910390fd5b5f60033387876002886040516020016113b291906125b8565b6040516020818303038152906040526040516113ce9190612624565b602060405180830381855afa1580156113e9573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061140c919061264e565b878760405160200161142396959493929190612895565b60405160208183030381529060405260405161143f9190612624565b602060405180830381855afa15801561145a573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146114e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114db906127a8565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561151a576115196123bc565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161154e91906127d5565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b815260040161159793929190612992565b5f604051808303815f87803b1580156115ae575f80fd5b505af11580156115c0573d5f803e3d5ffd5b505050505050505050505050565b600160038111156115e2576115e16123bc565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115611614576116136123bc565b5b14611654576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164b9061257a565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b990612eb3565b60405180910390fd5b5f60033388886002896040516020016116db91906125b8565b6040516020818303038152906040526040516116f79190612624565b602060405180830381855afa158015611712573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190611735919061264e565b88888860405160200161174e97969594939291906126de565b60405160208183030381529060405260405161176a9190612624565b602060405180830381855afa158015611785573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461180f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611806906127a8565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff02191690836003811115611845576118446123bc565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08860405161187991906127d5565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016118c4949392919061283f565b5f604051808303815f87803b1580156118db575f80fd5b505af11580156118ed573d5f803e3d5ffd5b50505050505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f8083838101906119599190612b1a565b90505f600381111561196e5761196d6123bc565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff1660038111156119a3576119a26123bc565b5b146119e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119da90612f41565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603611a55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4c90612c1d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603611ac7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611abe90612c85565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611b39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3090612d13565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614611ba7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9e90612d7b565b60405180910390fd5b5f8511611be9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be090612fa9565b60405180910390fd5b611bf68160200151611e45565b15611c36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2d90612de3565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c604051602001611c6697969594939291906126de565b604051602081830303815290604052604051611c829190612624565b602060405180830381855afa158015611c9d573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115611ced57611cec6123bc565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115611d8457611d836123bc565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051611dbe91906127d5565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611e9b81611e67565b8114611ea5575f80fd5b50565b5f81359050611eb681611e92565b92915050565b5f60208284031215611ed157611ed0611e5f565b5b5f611ede84828501611ea8565b91505092915050565b5f8115159050919050565b611efb81611ee7565b82525050565b5f602082019050611f145f830184611ef2565b92915050565b5f819050919050565b611f2c81611f1a565b8114611f36575f80fd5b50565b5f81359050611f4781611f23565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611f7682611f4d565b9050919050565b611f8681611f6c565b8114611f90575f80fd5b50565b5f81359050611fa181611f7d565b92915050565b5f819050919050565b611fb981611fa7565b8114611fc3575f80fd5b50565b5f81359050611fd481611fb0565b92915050565b5f805f805f805f60e0888a031215611ff557611ff4611e5f565b5b5f6120028a828b01611f39565b97505060206120138a828b01611f93565b96505060406120248a828b01611f39565b95505060606120358a828b01611f39565b94505060806120468a828b01611f93565b93505060a06120578a828b01611fc6565b92505060c06120688a828b01611fc6565b91505092959891949750929550565b5f805f805f8060c0878903121561209157612090611e5f565b5b5f61209e89828a01611f39565b96505060206120af89828a01611f93565b95505060406120c089828a01611f39565b94505060606120d189828a01611f39565b93505060806120e289828a01611f93565b92505060a06120f389828a01611fc6565b9150509295509295509295565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261212157612120612100565b5b8235905067ffffffffffffffff81111561213e5761213d612104565b5b60208301915083600182028301111561215a57612159612108565b5b9250929050565b5f805f805f6080868803121561217a57612179611e5f565b5b5f61218788828901611f93565b955050602061219888828901611f93565b94505060406121a988828901611fc6565b935050606086013567ffffffffffffffff8111156121ca576121c9611e63565b5b6121d68882890161210c565b92509250509295509295909350565b6121ee81611e67565b82525050565b5f6020820190506122075f8301846121e5565b92915050565b5f8083601f84011261222257612221612100565b5b8235905067ffffffffffffffff81111561223f5761223e612104565b5b60208301915083602082028301111561225b5761225a612108565b5b9250929050565b5f805f805f805f8060a0898b03121561227e5761227d611e5f565b5b5f61228b8b828c01611f93565b985050602061229c8b828c01611f93565b975050604089013567ffffffffffffffff8111156122bd576122bc611e63565b5b6122c98b828c0161220d565b9650965050606089013567ffffffffffffffff8111156122ec576122eb611e63565b5b6122f88b828c0161220d565b9450945050608089013567ffffffffffffffff81111561231b5761231a611e63565b5b6123278b828c0161210c565b92509250509295985092959890939650565b5f6020828403121561234e5761234d611e5f565b5b5f61235b84828501611f39565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b61239881612364565b82525050565b5f63ffffffff82169050919050565b6123b68161239e565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600481106123fa576123f96123bc565b5b50565b5f81905061240a826123e9565b919050565b5f612419826123fd565b9050919050565b6124298161240f565b82525050565b5f6060820190506124425f83018661238f565b61244f60208301856123ad565b61245c6040830184612420565b949350505050565b5f805f805f8060a0878903121561247e5761247d611e5f565b5b5f61248b89828a01611f93565b965050602061249c89828a01611f93565b95505060406124ad89828a01611fc6565b94505060606124be89828a01611fc6565b935050608087013567ffffffffffffffff8111156124df576124de611e63565b5b6124eb89828a0161210c565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f612564602a836124fa565b915061256f8261250a565b604082019050919050565b5f6020820190508181035f83015261259181612558565b9050919050565b5f819050919050565b6125b26125ad82611f1a565b612598565b82525050565b5f6125c382846125a1565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6125fe826125d2565b61260881856125dc565b93506126188185602086016125e6565b80840191505092915050565b5f61262f82846125f4565b915081905092915050565b5f8151905061264881611f23565b92915050565b5f6020828403121561266357612662611e5f565b5b5f6126708482850161263a565b91505092915050565b5f8160601b9050919050565b5f61268f82612679565b9050919050565b5f6126a082612685565b9050919050565b6126b86126b382611f6c565b612696565b82525050565b5f819050919050565b6126d86126d382611fa7565b6126be565b82525050565b5f6126e9828a6126a7565b6014820191506126f982896126a7565b60148201915061270982886125a1565b60208201915061271982876125a1565b60208201915061272982866126a7565b60148201915061273982856126c7565b60208201915061274982846126c7565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f6127926013836124fa565b915061279d8261275e565b602082019050919050565b5f6020820190508181035f8301526127bf81612786565b9050919050565b6127cf81611f1a565b82525050565b5f6020820190506127e85f8301846127c6565b92915050565b6127f781611f6c565b82525050565b61280681611fa7565b82525050565b5f82825260208201905092915050565b50565b5f61282a5f8361280c565b91506128358261281c565b5f82019050919050565b5f60a0820190506128525f8301876127ee565b61285f60208301866127ee565b61286c60408301856127fd565b61287960608301846127fd565b818103608083015261288a8161281f565b905095945050505050565b5f6128a082896126a7565b6014820191506128b082886126a7565b6014820191506128c082876125a1565b6020820191506128d082866125a1565b6020820191506128e082856126a7565b6014820191506128f082846126c7565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f61295e6038836124fa565b915061296982612904565b604082019050919050565b5f6020820190508181035f83015261298b81612952565b9050919050565b5f6060820190506129a55f8301866127ee565b6129b260208301856127ee565b6129bf60408301846127fd565b949350505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612a11826129cb565b810181811067ffffffffffffffff82111715612a3057612a2f6129db565b5b80604052505050565b5f612a42611e56565b9050612a4e8282612a08565b919050565b612a5c8161239e565b8114612a66575f80fd5b50565b5f81359050612a7781612a53565b92915050565b5f60c08284031215612a9257612a916129c7565b5b612a9c60c0612a39565b90505f612aab84828501611f39565b5f830152506020612abe84828501611f93565b6020830152506040612ad284828501611f93565b6040830152506060612ae684828501611f39565b6060830152506080612afa84828501611f39565b60808301525060a0612b0e84828501612a69565b60a08301525092915050565b5f60c08284031215612b2f57612b2e611e5f565b5b5f612b3c84828501612a7d565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f612b9f602a836124fa565b9150612baa82612b45565b604082019050919050565b5f6020820190508181035f830152612bcc81612b93565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612c07601e836124fa565b9150612c1282612bd3565b602082019050919050565b5f6020820190508181035f830152612c3481612bfb565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612c6f601e836124fa565b9150612c7a82612c3b565b602082019050919050565b5f6020820190508181035f830152612c9c81612c63565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f612cfd6023836124fa565b9150612d0882612ca3565b604082019050919050565b5f6020820190508181035f830152612d2a81612cf1565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f612d65601b836124fa565b9150612d7082612d31565b602082019050919050565b5f6020820190508181035f830152612d9281612d59565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f612dcd601a836124fa565b9150612dd882612d99565b602082019050919050565b5f6020820190508181035f830152612dfa81612dc1565b9050919050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f612e35601d836124fa565b9150612e4082612e01565b602082019050919050565b5f6020820190508181035f830152612e6281612e29565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f612e9d6015836124fa565b9150612ea882612e69565b602082019050919050565b5f6020820190508181035f830152612eca81612e91565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f612f2b602b836124fa565b9150612f3682612ed1565b604082019050919050565b5f6020820190508181035f830152612f5881612f1f565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f612f93601c836124fa565b9150612f9e82612f5f565b602082019050919050565b5f6020820190508181035f830152612fc081612f87565b905091905056fea26469706673582212204e239c256ffaf5624f6d55ae2e9f8afd626e0e129a36ff33221d4b2fe58f6b5a64736f6c63430008190033"; +pub const NFT_MAKER_SWAP_V2_BYTES: &str = "6080604052348015600e575f80fd5b506131fa8061001c5f395ff3fe608060405234801561000f575f80fd5b50600436106100cd575f3560e01c8063bc197c811161008a578063eb4ab61211610064578063eb4ab61214610209578063efccb9eb14610225578063f0e9fcd114610257578063f23a6e6114610273576100cd565b8063bc197c81146101a1578063c8d9009b146101d1578063c92cd12d146101ed576100cd565b806301ffc9a7146100d157806305ec158d146101015780630f235fce1461011d578063150b7a02146101395780636e6bf6d214610169578063b27e46fb14610185575b5f80fd5b6100eb60048036038101906100e69190612005565b6102a3565b6040516100f8919061204a565b60405180910390f35b61011b60048036038101906101169190612123565b610384565b005b610137600480360381019061013291906121c0565b610644565b005b610153600480360381019061014e91906122aa565b6108fe565b604051610160919061233d565b60405180910390f35b610183600480360381019061017e91906121c0565b610d4d565b005b61019f600480360381019061019a9190612123565b611008565b005b6101bb60048036038101906101b691906123ab565b6112c7565b6040516101c8919061233d565b60405180910390f35b6101eb60048036038101906101e691906121c0565b611303565b005b61020760048036038101906102029190612123565b61162c565b005b610223600480360381019061021e9190612482565b61195a565b005b61023f600480360381019061023a91906124e6565b6119d1565b60405161024e939291906125dc565b60405180910390f35b610271600480360381019061026c9190612611565b611a1d565b005b61028d60048036038101906102889190612661565b611a91565b60405161029a919061233d565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061036d57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061037d575061037c82611f25565b5b9050919050565b6001600381111561039857610397612569565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff1660038111156103ca576103c9612569565b5b1461040a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161040190612777565b60405180910390fd5b5f6003873360028960405160200161042291906127b5565b60405160208183030381529060405260405161043e9190612821565b602060405180830381855afa158015610459573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061047c919061284b565b8888888860405160200161049697969594939291906128db565b6040516020818303038152906040526040516104b29190612821565b602060405180830381855afa1580156104cd573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610557576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161054e906129a5565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561058d5761058c612569565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd73886040516105c191906129d2565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161060c9493929190612a3c565b5f604051808303815f87803b158015610623575f80fd5b505af1158015610635573d5f803e3d5ffd5b50505050505050505050505050565b6001600381111561065857610657612569565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561068a57610689612569565b5b146106ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c190612777565b60405180910390fd5b5f60038633878787876040516020016106e896959493929190612a92565b6040516020818303038152906040526040516107049190612821565b602060405180830381855afa15801561071f573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146107a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107a0906129a5565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610814576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161080b90612b71565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561084a57610849612569565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad192190728760405161087e91906129d2565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016108c793929190612b8f565b5f604051808303815f87803b1580156108de575f80fd5b505af11580156108f0573d5f803e3d5ffd5b505050505050505050505050565b5f80838381019061090f9190612d17565b90505f600381111561092457610923612569565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff16600381111561095957610958612569565b5b14610999576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099090612db2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603610a0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0290612e1a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610a7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7490612e82565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610aef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae690612f10565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610b5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5490612f78565b60405180910390fd5b610b6a8160200151611f8e565b15610baa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba190612fe0565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610bd896959493929190612a92565b604051602081830303815290604052604051610bf49190612821565b602060405180830381855afa158015610c0f573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115610c5f57610c5e612569565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115610cf657610cf5612569565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051610d3091906129d2565b60405180910390a163150b7a0260e01b9250505095945050505050565b60016003811115610d6157610d60612569565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff166003811115610d9357610d92612569565b5b14610dd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dca90612777565b60405180910390fd5b5f60038633600288604051602001610deb91906127b5565b604051602081830303815290604052604051610e079190612821565b602060405180830381855afa158015610e22573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610e45919061284b565b878787604051602001610e5d96959493929190612a92565b604051602081830303815290604052604051610e799190612821565b602060405180830381855afa158015610e94573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610f1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f15906129a5565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610f5457610f53612569565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051610f8891906129d2565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610fd193929190612b8f565b5f604051808303815f87803b158015610fe8575f80fd5b505af1158015610ffa573d5f803e3d5ffd5b505050505050505050505050565b6001600381111561101c5761101b612569565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561104e5761104d612569565b5b1461108e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108590612777565b60405180910390fd5b5f6003873388888888886040516020016110ae97969594939291906128db565b6040516020818303038152906040526040516110ca9190612821565b602060405180830381855afa1580156110e5573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461116f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611166906129a5565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156111da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d190612b71565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156112105761120f612569565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad192190728860405161124491906129d2565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161128f9493929190612a3c565b5f604051808303815f87803b1580156112a6575f80fd5b505af11580156112b8573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112fa90613048565b60405180910390fd5b6001600381111561131757611316612569565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561134957611348612569565b5b14611389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138090612777565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ee906130b0565b60405180910390fd5b5f600333878760028860405160200161141091906127b5565b60405160208183030381529060405260405161142c9190612821565b602060405180830381855afa158015611447573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061146a919061284b565b878760405160200161148196959493929190612a92565b60405160208183030381529060405260405161149d9190612821565b602060405180830381855afa1580156114b8573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611542576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611539906129a5565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561157857611577612569565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0876040516115ac91906129d2565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016115f593929190612b8f565b5f604051808303815f87803b15801561160c575f80fd5b505af115801561161e573d5f803e3d5ffd5b505050505050505050505050565b600160038111156116405761163f612569565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561167257611671612569565b5b146116b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a990612777565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611720576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611717906130b0565b60405180910390fd5b5f600333888860028960405160200161173991906127b5565b6040516020818303038152906040526040516117559190612821565b602060405180830381855afa158015611770573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190611793919061284b565b8888886040516020016117ac97969594939291906128db565b6040516020818303038152906040526040516117c89190612821565b602060405180830381855afa1580156117e3573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461186d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611864906129a5565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156118a3576118a2612569565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0886040516118d791906129d2565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016119229493929190612a3c565b5f604051808303815f87803b158015611939575f80fd5b505af115801561194b573d5f803e3d5ffd5b50505050505050505050505050565b5f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a308487876040518563ffffffff1660e01b815260040161199d9493929190612a3c565b5f604051808303815f87803b1580156119b4575f80fd5b505af11580156119c6573d5f803e3d5ffd5b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3084866040518463ffffffff1660e01b8152600401611a5e93929190612b8f565b5f604051808303815f87803b158015611a75575f80fd5b505af1158015611a87573d5f803e3d5ffd5b5050505050505050565b5f808383810190611aa29190612d17565b90505f6003811115611ab757611ab6612569565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff166003811115611aec57611aeb612569565b5b14611b2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b239061313e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603611b9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9590612e1a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603611c10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c0790612e82565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7990612f10565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614611cf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce790612f78565b60405180910390fd5b5f8511611d32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d29906131a6565b60405180910390fd5b611d3f8160200151611f8e565b15611d7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7690612fe0565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c604051602001611daf97969594939291906128db565b604051602081830303815290604052604051611dcb9190612821565b602060405180830381855afa158015611de6573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115611e3657611e35612569565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115611ecd57611ecc612569565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051611f0791906129d2565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611fe481611fb0565b8114611fee575f80fd5b50565b5f81359050611fff81611fdb565b92915050565b5f6020828403121561201a57612019611fa8565b5b5f61202784828501611ff1565b91505092915050565b5f8115159050919050565b61204481612030565b82525050565b5f60208201905061205d5f83018461203b565b92915050565b5f819050919050565b61207581612063565b811461207f575f80fd5b50565b5f813590506120908161206c565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6120bf82612096565b9050919050565b6120cf816120b5565b81146120d9575f80fd5b50565b5f813590506120ea816120c6565b92915050565b5f819050919050565b612102816120f0565b811461210c575f80fd5b50565b5f8135905061211d816120f9565b92915050565b5f805f805f805f60e0888a03121561213e5761213d611fa8565b5b5f61214b8a828b01612082565b975050602061215c8a828b016120dc565b965050604061216d8a828b01612082565b955050606061217e8a828b01612082565b945050608061218f8a828b016120dc565b93505060a06121a08a828b0161210f565b92505060c06121b18a828b0161210f565b91505092959891949750929550565b5f805f805f8060c087890312156121da576121d9611fa8565b5b5f6121e789828a01612082565b96505060206121f889828a016120dc565b955050604061220989828a01612082565b945050606061221a89828a01612082565b935050608061222b89828a016120dc565b92505060a061223c89828a0161210f565b9150509295509295509295565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261226a57612269612249565b5b8235905067ffffffffffffffff8111156122875761228661224d565b5b6020830191508360018202830111156122a3576122a2612251565b5b9250929050565b5f805f805f608086880312156122c3576122c2611fa8565b5b5f6122d0888289016120dc565b95505060206122e1888289016120dc565b94505060406122f28882890161210f565b935050606086013567ffffffffffffffff81111561231357612312611fac565b5b61231f88828901612255565b92509250509295509295909350565b61233781611fb0565b82525050565b5f6020820190506123505f83018461232e565b92915050565b5f8083601f84011261236b5761236a612249565b5b8235905067ffffffffffffffff8111156123885761238761224d565b5b6020830191508360208202830111156123a4576123a3612251565b5b9250929050565b5f805f805f805f8060a0898b0312156123c7576123c6611fa8565b5b5f6123d48b828c016120dc565b98505060206123e58b828c016120dc565b975050604089013567ffffffffffffffff81111561240657612405611fac565b5b6124128b828c01612356565b9650965050606089013567ffffffffffffffff81111561243557612434611fac565b5b6124418b828c01612356565b9450945050608089013567ffffffffffffffff81111561246457612463611fac565b5b6124708b828c01612255565b92509250509295985092959890939650565b5f805f806080858703121561249a57612499611fa8565b5b5f6124a7878288016120dc565b94505060206124b88782880161210f565b93505060406124c98782880161210f565b92505060606124da878288016120dc565b91505092959194509250565b5f602082840312156124fb576124fa611fa8565b5b5f61250884828501612082565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b61254581612511565b82525050565b5f63ffffffff82169050919050565b6125638161254b565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600481106125a7576125a6612569565b5b50565b5f8190506125b782612596565b919050565b5f6125c6826125aa565b9050919050565b6125d6816125bc565b82525050565b5f6060820190506125ef5f83018661253c565b6125fc602083018561255a565b61260960408301846125cd565b949350505050565b5f805f6060848603121561262857612627611fa8565b5b5f612635868287016120dc565b93505060206126468682870161210f565b9250506040612657868287016120dc565b9150509250925092565b5f805f805f8060a0878903121561267b5761267a611fa8565b5b5f61268889828a016120dc565b965050602061269989828a016120dc565b95505060406126aa89828a0161210f565b94505060606126bb89828a0161210f565b935050608087013567ffffffffffffffff8111156126dc576126db611fac565b5b6126e889828a01612255565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f612761602a836126f7565b915061276c82612707565b604082019050919050565b5f6020820190508181035f83015261278e81612755565b9050919050565b5f819050919050565b6127af6127aa82612063565b612795565b82525050565b5f6127c0828461279e565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6127fb826127cf565b61280581856127d9565b93506128158185602086016127e3565b80840191505092915050565b5f61282c82846127f1565b915081905092915050565b5f815190506128458161206c565b92915050565b5f602082840312156128605761285f611fa8565b5b5f61286d84828501612837565b91505092915050565b5f8160601b9050919050565b5f61288c82612876565b9050919050565b5f61289d82612882565b9050919050565b6128b56128b0826120b5565b612893565b82525050565b5f819050919050565b6128d56128d0826120f0565b6128bb565b82525050565b5f6128e6828a6128a4565b6014820191506128f682896128a4565b601482019150612906828861279e565b602082019150612916828761279e565b60208201915061292682866128a4565b60148201915061293682856128c4565b60208201915061294682846128c4565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f61298f6013836126f7565b915061299a8261295b565b602082019050919050565b5f6020820190508181035f8301526129bc81612983565b9050919050565b6129cc81612063565b82525050565b5f6020820190506129e55f8301846129c3565b92915050565b6129f4816120b5565b82525050565b612a03816120f0565b82525050565b5f82825260208201905092915050565b50565b5f612a275f83612a09565b9150612a3282612a19565b5f82019050919050565b5f60a082019050612a4f5f8301876129eb565b612a5c60208301866129eb565b612a6960408301856129fa565b612a7660608301846129fa565b8181036080830152612a8781612a1c565b905095945050505050565b5f612a9d82896128a4565b601482019150612aad82886128a4565b601482019150612abd828761279e565b602082019150612acd828661279e565b602082019150612add82856128a4565b601482019150612aed82846128c4565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f612b5b6038836126f7565b9150612b6682612b01565b604082019050919050565b5f6020820190508181035f830152612b8881612b4f565b9050919050565b5f606082019050612ba25f8301866129eb565b612baf60208301856129eb565b612bbc60408301846129fa565b949350505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612c0e82612bc8565b810181811067ffffffffffffffff82111715612c2d57612c2c612bd8565b5b80604052505050565b5f612c3f611f9f565b9050612c4b8282612c05565b919050565b612c598161254b565b8114612c63575f80fd5b50565b5f81359050612c7481612c50565b92915050565b5f60c08284031215612c8f57612c8e612bc4565b5b612c9960c0612c36565b90505f612ca884828501612082565b5f830152506020612cbb848285016120dc565b6020830152506040612ccf848285016120dc565b6040830152506060612ce384828501612082565b6060830152506080612cf784828501612082565b60808301525060a0612d0b84828501612c66565b60a08301525092915050565b5f60c08284031215612d2c57612d2b611fa8565b5b5f612d3984828501612c7a565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f612d9c602a836126f7565b9150612da782612d42565b604082019050919050565b5f6020820190508181035f830152612dc981612d90565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612e04601e836126f7565b9150612e0f82612dd0565b602082019050919050565b5f6020820190508181035f830152612e3181612df8565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612e6c601e836126f7565b9150612e7782612e38565b602082019050919050565b5f6020820190508181035f830152612e9981612e60565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f612efa6023836126f7565b9150612f0582612ea0565b604082019050919050565b5f6020820190508181035f830152612f2781612eee565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f612f62601b836126f7565b9150612f6d82612f2e565b602082019050919050565b5f6020820190508181035f830152612f8f81612f56565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f612fca601a836126f7565b9150612fd582612f96565b602082019050919050565b5f6020820190508181035f830152612ff781612fbe565b9050919050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f613032601d836126f7565b915061303d82612ffe565b602082019050919050565b5f6020820190508181035f83015261305f81613026565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f61309a6015836126f7565b91506130a582613066565b602082019050919050565b5f6020820190508181035f8301526130c78161308e565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f613128602b836126f7565b9150613133826130ce565b604082019050919050565b5f6020820190508181035f8301526131558161311c565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f613190601c836126f7565b915061319b8261315c565b602082019050919050565b5f6020820190508181035f8301526131bd81613184565b905091905056fea2646970667358221220c7235610f4c08b95d1e01bd31ff0b8b671c0f18c33212760a2ce3b09e6ad77e964736f6c63430008190033"; pub trait CoinDockerOps { fn rpc_client(&self) -> &UtxoRpcClientEnum; diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 8d8ebf1ffe..87cd590918 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1179,12 +1179,11 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { let token_id = 3u32; let erc721_nft = TestNftType::Erc721 { token_id }; - let maker_global_nft = get_or_create_nft(&MM_CTX, SEPOLIA_MAKER_PRIV, Some(erc721_nft)); - let taker_global_nft = get_or_create_nft(&MM_CTX1, SEPOLIA_TAKER_PRIV, None); + let maker_global_nft = global_nft_with_random_privkey(nft_maker_swap_v2(), Some(erc721_nft)); + let taker_global_nft = global_nft_with_random_privkey(nft_maker_swap_v2(), None); let maker_address = block_on(maker_global_nft.my_addr()); let taker_address = block_on(taker_global_nft.my_addr()); - wait_pending_transactions(maker_address); let time_lock_to_refund = now_sec() - 1000; log!("time_lock_to_refund: {}", time_lock_to_refund); @@ -1192,14 +1191,14 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { let maker_secret = &[1; 32]; let maker_secret_hash = sha256(maker_secret).to_vec(); - let taker_secret = &[2; 32]; + let taker_secret = &[0; 32]; let taker_secret_hash = sha256(taker_secret).to_vec(); let nft_swap_info = NftSwapInfo { - token_address: &sepolia_erc721(), + token_address: &erc721_contract(), token_id: &BigUint::from(token_id).to_bytes(), contract_type: &ContractType::Erc721, - swap_contract_address: &sepolia_etomic_maker_nft(), + swap_contract_address: &nft_maker_swap_v2(), }; let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { @@ -1226,8 +1225,6 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { }; maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - wait_pending_transactions(maker_address); - // let raw_tx_hex = "f9012e7785103a6708f8830249f0949eb88cd58605d8fb9b14652d6152727f7e95fb4d80b8c40f235fce0367f2f8f78bb4d8f2b6267e20ef7b5467e183315546049e2a88443230bd0b3100000000000000000000000016e281a9f2e7581269a13e516aa79d6a4a1cd98075877bb41d393b5fb8455ce60ecd8dda001d06316496b14dfa7f895656eeca4a72cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000000000000000000000000bac1c9f2087f39caaa4e93412c6412809186870e00000000000000000000000000000000000000000000000000000000000000028401546d71a0cf6e0876226c1cec668423b59eebe2bb22bbfc8f1d39914633d2555ff7bcbd8ca016f46356ad917fb268a0386946cc66b868339d593db3060f60bcb1262d2b4f9a"; // let maker_payment_to_refund = maker_global_nft.parse_tx(raw_tx_hex.as_bytes()).unwrap(); @@ -1236,7 +1233,7 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { &maker_address, &taker_secret_hash, &maker_secret_hash, - &sepolia_erc721(), + &erc721_contract(), token_id, ); println!("payment_hash_refund: {:?}", payment_hash_refund); @@ -1248,7 +1245,7 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { taker_secret, swap_unique_data: &[], contract_type: &ContractType::Erc721, - swap_contract_address: &sepolia_etomic_maker_nft(), + swap_contract_address: &nft_maker_swap_v2(), }; let refund_timelock_tx = block_on(taker_global_nft.refund_nft_maker_payment_v2_timelock(refund_timelock_args)).unwrap(); @@ -1282,7 +1279,7 @@ fn calculate_payment_hash( // Convert token_id to a 256-bit representation as Solidity does with abi.encodePacked let token_id_bytes = { let mut buf = [0u8; 32]; - buf[24..32].copy_from_slice(&token_id.to_be_bytes()); + buf[28..32].copy_from_slice(&token_id.to_be_bytes()); buf }; From e2f8ccf6a6a69ac2a60b158a715f953dc89f6ef0 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 28 May 2024 17:34:20 +0700 Subject: [PATCH 043/233] call maker_global_nft.refund_nft_maker_payment_v2_timelock --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 87cd590918..e53c61d725 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1248,7 +1248,7 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { swap_contract_address: &nft_maker_swap_v2(), }; let refund_timelock_tx = - block_on(taker_global_nft.refund_nft_maker_payment_v2_timelock(refund_timelock_args)).unwrap(); + block_on(maker_global_nft.refund_nft_maker_payment_v2_timelock(refund_timelock_args)).unwrap(); log!( "Maker refunded ERC721 NFT Maker payment Timelock, tx hash: {:02x}", refund_timelock_tx.tx_hash() From dad6988fd3d09b2e2026a14fffe398934881c0c0 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 28 May 2024 18:03:22 +0700 Subject: [PATCH 044/233] use get_erc712_owner func in refund erc721 test --- .../tests/docker_tests/eth_docker_tests.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index e53c61d725..5758aa3c02 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -179,6 +179,12 @@ fn erc712_owner(token_id: U256) -> Address { block_on(erc721_contract.query("ownerOf", Token::Uint(token_id), None, Options::default(), None)).unwrap() } +fn get_erc712_owner(token_id: U256) -> Address { + let _guard = GETH_NONCE_LOCK.lock().unwrap(); + let erc721_contract = Contract::from_json(GETH_WEB3.eth(), erc721_contract(), ERC721_TEST_ABI.as_bytes()).unwrap(); + block_on(erc721_contract.query("ownerOf", Token::Uint(token_id), None, Options::default(), None)).unwrap() +} + #[allow(dead_code)] fn mint_erc1155(to_addr: Address, token_id: U256, amount: U256) { let _guard = GETH_NONCE_LOCK.lock().unwrap(); @@ -1183,7 +1189,9 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { let taker_global_nft = global_nft_with_random_privkey(nft_maker_swap_v2(), None); let maker_address = block_on(maker_global_nft.my_addr()); + log!("maker_address: {:?}", maker_address); let taker_address = block_on(taker_global_nft.my_addr()); + log!("taker_address: {:?}", taker_address); let time_lock_to_refund = now_sec() - 1000; log!("time_lock_to_refund: {}", time_lock_to_refund); @@ -1225,9 +1233,6 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { }; maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - // let raw_tx_hex = "f9012e7785103a6708f8830249f0949eb88cd58605d8fb9b14652d6152727f7e95fb4d80b8c40f235fce0367f2f8f78bb4d8f2b6267e20ef7b5467e183315546049e2a88443230bd0b3100000000000000000000000016e281a9f2e7581269a13e516aa79d6a4a1cd98075877bb41d393b5fb8455ce60ecd8dda001d06316496b14dfa7f895656eeca4a72cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000000000000000000000000bac1c9f2087f39caaa4e93412c6412809186870e00000000000000000000000000000000000000000000000000000000000000028401546d71a0cf6e0876226c1cec668423b59eebe2bb22bbfc8f1d39914633d2555ff7bcbd8ca016f46356ad917fb268a0386946cc66b868339d593db3060f60bcb1262d2b4f9a"; - // let maker_payment_to_refund = maker_global_nft.parse_tx(raw_tx_hex.as_bytes()).unwrap(); - let payment_hash_refund = calculate_payment_hash( &taker_address, &maker_address, @@ -1238,6 +1243,9 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { ); println!("payment_hash_refund: {:?}", payment_hash_refund); + let current_owner = get_erc712_owner(U256::from(token_id)); + assert_eq!(current_owner, nft_maker_swap_v2()); + let refund_timelock_args = RefundNftMakerPaymentArgs { maker_payment_tx: &maker_payment_to_refund, taker_secret_hash: &taker_secret_hash, @@ -1262,7 +1270,7 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { }; maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - let current_owner = erc712_owner(U256::from(1)); + let current_owner = get_erc712_owner(U256::from(token_id)); assert_eq!(current_owner, maker_address); } From 9b1a700b166f03824e99c6bff4868d8f4778da40 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 28 May 2024 18:26:17 +0700 Subject: [PATCH 045/233] add geth_ prefix to Address functions in eth tests --- mm2src/coins/eth/nft_swap_v2/mod.rs | 19 ---- .../tests/docker_tests/docker_tests_common.rs | 1 + .../tests/docker_tests/eth_docker_tests.rs | 100 ++++++------------ 3 files changed, 33 insertions(+), 87 deletions(-) diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index 085eb00ea7..7bef8ae01d 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -31,12 +31,10 @@ impl EthCoin { args.nft_swap_info.contract_type )); let htlc_data = try_tx_s!(self.prepare_htlc_data(&args)); - println!("encoded htlc_data to send payment: {:?}", htlc_data); match &self.coin_type { EthCoinType::Nft { .. } => { let data = try_tx_s!(self.prepare_nft_maker_payment_v2_data(&args, htlc_data).await); - println!("encoded tx send payment data: {:?}", data); self.sign_and_send_transaction( 0.into(), Action::Call(*args.nft_swap_info.token_address), @@ -315,19 +313,6 @@ impl EthCoin { .await?; let decoded_tokens = function.decode_output(&bytes.0)?; - println!( - "decoded makerPayments paymentHash: {:?}", - decoded_tokens.get(0).unwrap() - ); - println!( - "decoded makerPayments paymentLockTime: {:?}", - decoded_tokens.get(1).unwrap() - ); - println!( - "decoded makerPayments MakerPaymentState: {:?}", - decoded_tokens.get(2).unwrap() - ); - let state = decoded_tokens .get(2) .ok_or_else(|| PaymentStatusErr::Internal(ERRL!("Payment status must contain 'state' as the 2nd token")))?; @@ -427,10 +412,6 @@ impl EthCoin { decoded[2].clone(), // tokenId ], }; - println!("htlc_params: {:?}", htlc_params); - println!("args.taker_secret_hash: {:?}", args.taker_secret_hash); - println!("args.maker_secret_hash: {:?}", args.maker_secret_hash); - println!("decoded: {:?}", decoded); let data = refund_func.encode_input(&input_tokens)?; Ok(data) } diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index a4506f1c11..2596e4eed9 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -132,6 +132,7 @@ pub const WATCHERS_SWAP_CONTRACT_BYTES: &str = "608060405234801561000f575f80fd5b pub const ERC721_TEST_TOKEN_BYTES: &str = "608060405234801562000010575f80fd5b50604051620022ac380380620022ac8339818101604052810190620000369190620001ea565b8181815f9081620000489190620004a4565b5080600190816200005a9190620004a4565b505050505062000588565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c6826200007e565b810181811067ffffffffffffffff82111715620000e857620000e76200008e565b5b80604052505050565b5f620000fc62000065565b90506200010a8282620000bb565b919050565b5f67ffffffffffffffff8211156200012c576200012b6200008e565b5b62000137826200007e565b9050602081019050919050565b5f5b838110156200016357808201518184015260208101905062000146565b5f8484015250505050565b5f620001846200017e846200010f565b620000f1565b905082815260208101848484011115620001a357620001a26200007a565b5b620001b084828562000144565b509392505050565b5f82601f830112620001cf57620001ce62000076565b5b8151620001e18482602086016200016e565b91505092915050565b5f80604083850312156200020357620002026200006e565b5b5f83015167ffffffffffffffff81111562000223576200022262000072565b5b6200023185828601620001b8565b925050602083015167ffffffffffffffff81111562000255576200025462000072565b5b6200026385828601620001b8565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620002bc57607f821691505b602082108103620002d257620002d162000277565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002f9565b620003428683620002f9565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200038c6200038662000380846200035a565b62000363565b6200035a565b9050919050565b5f819050919050565b620003a7836200036c565b620003bf620003b68262000393565b84845462000305565b825550505050565b5f90565b620003d5620003c7565b620003e28184846200039c565b505050565b5b818110156200040957620003fd5f82620003cb565b600181019050620003e8565b5050565b601f82111562000458576200042281620002d8565b6200042d84620002ea565b810160208510156200043d578190505b620004556200044c85620002ea565b830182620003e7565b50505b505050565b5f82821c905092915050565b5f6200047a5f19846008026200045d565b1980831691505092915050565b5f62000494838362000469565b9150826002028217905092915050565b620004af826200026d565b67ffffffffffffffff811115620004cb57620004ca6200008e565b5b620004d78254620002a4565b620004e48282856200040d565b5f60209050601f8311600181146200051a575f841562000505578287015190505b62000511858262000487565b86555062000580565b601f1984166200052a86620002d8565b5f5b8281101562000553578489015182556001820191506020850194506020810190506200052c565b868310156200057357848901516200056f601f89168262000469565b8355505b6001600288020188555050505b505050505050565b611d1680620005965f395ff3fe608060405234801561000f575f80fd5b50600436106100e8575f3560e01c80636352211e1161008a578063a22cb46511610064578063a22cb46514610258578063b88d4fde14610274578063c87b56dd14610290578063e985e9c5146102c0576100e8565b80636352211e146101da57806370a082311461020a57806395d89b411461023a576100e8565b8063095ea7b3116100c6578063095ea7b31461016a57806323b872dd1461018657806340c10f19146101a257806342842e0e146101be576100e8565b806301ffc9a7146100ec57806306fdde031461011c578063081812fc1461013a575b5f80fd5b610106600480360381019061010191906115a7565b6102f0565b60405161011391906115ec565b60405180910390f35b6101246103d1565b604051610131919061168f565b60405180910390f35b610154600480360381019061014f91906116e2565b610460565b604051610161919061174c565b60405180910390f35b610184600480360381019061017f919061178f565b61047b565b005b6101a0600480360381019061019b91906117cd565b610491565b005b6101bc60048036038101906101b7919061178f565b610590565b005b6101d860048036038101906101d391906117cd565b61059e565b005b6101f460048036038101906101ef91906116e2565b6105bd565b604051610201919061174c565b60405180910390f35b610224600480360381019061021f919061181d565b6105ce565b6040516102319190611857565b60405180910390f35b610242610684565b60405161024f919061168f565b60405180910390f35b610272600480360381019061026d919061189a565b610714565b005b61028e60048036038101906102899190611a04565b61072a565b005b6102aa60048036038101906102a591906116e2565b610747565b6040516102b7919061168f565b60405180910390f35b6102da60048036038101906102d59190611a84565b6107ad565b6040516102e791906115ec565b60405180910390f35b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103ba57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103ca57506103c98261083b565b5b9050919050565b60605f80546103df90611aef565b80601f016020809104026020016040519081016040528092919081815260200182805461040b90611aef565b80156104565780601f1061042d57610100808354040283529160200191610456565b820191905f5260205f20905b81548152906001019060200180831161043957829003601f168201915b5050505050905090565b5f61046a826108a4565b506104748261092a565b9050919050565b61048d8282610488610963565b61096a565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610501575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016104f8919061174c565b60405180910390fd5b5f610514838361050f610963565b61097c565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461058a578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161058193929190611b1f565b60405180910390fd5b50505050565b61059a8282610b87565b5050565b6105b883838360405180602001604052805f81525061072a565b505050565b5f6105c7826108a4565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361063f575f6040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401610636919061174c565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b60606001805461069390611aef565b80601f01602080910402602001604051908101604052809291908181526020018280546106bf90611aef565b801561070a5780601f106106e15761010080835404028352916020019161070a565b820191905f5260205f20905b8154815290600101906020018083116106ed57829003601f168201915b5050505050905090565b61072661071f610963565b8383610c7a565b5050565b610735848484610491565b61074184848484610de3565b50505050565b6060610752826108a4565b505f61075c610f95565b90505f81511161077a5760405180602001604052805f8152506107a5565b8061078484610fab565b604051602001610795929190611b8e565b6040516020818303038152906040525b915050919050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f806108af83611075565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361092157826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016109189190611857565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b61097783838360016110ae565b505050565b5f8061098784611075565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146109c8576109c781848661126d565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a5357610a075f855f806110ae565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610ad257600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610bf7575f6040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610bee919061174c565b60405180910390fd5b5f610c0383835f61097c565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c75575f6040517f73c6ac6e000000000000000000000000000000000000000000000000000000008152600401610c6c919061174c565b60405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610cea57816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401610ce1919061174c565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610dd691906115ec565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b1115610f8f578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02610e26610963565b8685856040518563ffffffff1660e01b8152600401610e489493929190611c03565b6020604051808303815f875af1925050508015610e8357506040513d601f19601f82011682018060405250810190610e809190611c61565b60015b610f04573d805f8114610eb1576040519150601f19603f3d011682016040523d82523d5f602084013e610eb6565b606091505b505f815103610efc57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610ef3919061174c565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614610f8d57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610f84919061174c565b60405180910390fd5b505b50505050565b606060405180602001604052805f815250905090565b60605f6001610fb984611330565b0190505f8167ffffffffffffffff811115610fd757610fd66118e0565b5b6040519080825280601f01601f1916602001820160405280156110095781602001600182028036833780820191505090505b5090505f82602001820190505b60011561106a578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161105f5761105e611c8c565b5b0494505f8503611016575b819350505050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b80806110e657505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611218575f6110f5846108a4565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561115f57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611172575061117081846107ad565b155b156111b457826040517fa9fbf51f0000000000000000000000000000000000000000000000000000000081526004016111ab919061174c565b60405180910390fd5b811561121657838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b611278838383611481565b61132b575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036112ec57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016112e39190611857565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401611322929190611cb9565b60405180910390fd5b505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061138c577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161138257611381611c8c565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106113c9576d04ee2d6d415b85acef810000000083816113bf576113be611c8c565b5b0492506020810190505b662386f26fc1000083106113f857662386f26fc1000083816113ee576113ed611c8c565b5b0492506010810190505b6305f5e1008310611421576305f5e100838161141757611416611c8c565b5b0492506008810190505b612710831061144657612710838161143c5761143b611c8c565b5b0492506004810190505b60648310611469576064838161145f5761145e611c8c565b5b0492506002810190505b600a8310611478576001810190505b80915050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561153857508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806114f957506114f884846107ad565b5b8061153757508273ffffffffffffffffffffffffffffffffffffffff1661151f8361092a565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61158681611552565b8114611590575f80fd5b50565b5f813590506115a18161157d565b92915050565b5f602082840312156115bc576115bb61154a565b5b5f6115c984828501611593565b91505092915050565b5f8115159050919050565b6115e6816115d2565b82525050565b5f6020820190506115ff5f8301846115dd565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561163c578082015181840152602081019050611621565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61166182611605565b61166b818561160f565b935061167b81856020860161161f565b61168481611647565b840191505092915050565b5f6020820190508181035f8301526116a78184611657565b905092915050565b5f819050919050565b6116c1816116af565b81146116cb575f80fd5b50565b5f813590506116dc816116b8565b92915050565b5f602082840312156116f7576116f661154a565b5b5f611704848285016116ce565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6117368261170d565b9050919050565b6117468161172c565b82525050565b5f60208201905061175f5f83018461173d565b92915050565b61176e8161172c565b8114611778575f80fd5b50565b5f8135905061178981611765565b92915050565b5f80604083850312156117a5576117a461154a565b5b5f6117b28582860161177b565b92505060206117c3858286016116ce565b9150509250929050565b5f805f606084860312156117e4576117e361154a565b5b5f6117f18682870161177b565b93505060206118028682870161177b565b9250506040611813868287016116ce565b9150509250925092565b5f602082840312156118325761183161154a565b5b5f61183f8482850161177b565b91505092915050565b611851816116af565b82525050565b5f60208201905061186a5f830184611848565b92915050565b611879816115d2565b8114611883575f80fd5b50565b5f8135905061189481611870565b92915050565b5f80604083850312156118b0576118af61154a565b5b5f6118bd8582860161177b565b92505060206118ce85828601611886565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61191682611647565b810181811067ffffffffffffffff82111715611935576119346118e0565b5b80604052505050565b5f611947611541565b9050611953828261190d565b919050565b5f67ffffffffffffffff821115611972576119716118e0565b5b61197b82611647565b9050602081019050919050565b828183375f83830152505050565b5f6119a86119a384611958565b61193e565b9050828152602081018484840111156119c4576119c36118dc565b5b6119cf848285611988565b509392505050565b5f82601f8301126119eb576119ea6118d8565b5b81356119fb848260208601611996565b91505092915050565b5f805f8060808587031215611a1c57611a1b61154a565b5b5f611a298782880161177b565b9450506020611a3a8782880161177b565b9350506040611a4b878288016116ce565b925050606085013567ffffffffffffffff811115611a6c57611a6b61154e565b5b611a78878288016119d7565b91505092959194509250565b5f8060408385031215611a9a57611a9961154a565b5b5f611aa78582860161177b565b9250506020611ab88582860161177b565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611b0657607f821691505b602082108103611b1957611b18611ac2565b5b50919050565b5f606082019050611b325f83018661173d565b611b3f6020830185611848565b611b4c604083018461173d565b949350505050565b5f81905092915050565b5f611b6882611605565b611b728185611b54565b9350611b8281856020860161161f565b80840191505092915050565b5f611b998285611b5e565b9150611ba58284611b5e565b91508190509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f611bd582611bb1565b611bdf8185611bbb565b9350611bef81856020860161161f565b611bf881611647565b840191505092915050565b5f608082019050611c165f83018761173d565b611c23602083018661173d565b611c306040830185611848565b8181036060830152611c428184611bcb565b905095945050505050565b5f81519050611c5b8161157d565b92915050565b5f60208284031215611c7657611c7561154a565b5b5f611c8384828501611c4d565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f604082019050611ccc5f83018561173d565b611cd96020830184611848565b939250505056fea26469706673582212207439b47c2a9a1624955997732075917bbf1da26949d000c778f561eb5687576164736f6c63430008180033"; pub const ERC1155_TEST_TOKEN_BYTES: &str = "608060405234801562000010575f80fd5b50604051620024eb380380620024eb8339818101604052810190620000369190620001ea565b8062000048816200005060201b60201c565b505062000554565b806002908162000061919062000470565b5050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c6826200007e565b810181811067ffffffffffffffff82111715620000e857620000e76200008e565b5b80604052505050565b5f620000fc62000065565b90506200010a8282620000bb565b919050565b5f67ffffffffffffffff8211156200012c576200012b6200008e565b5b62000137826200007e565b9050602081019050919050565b5f5b838110156200016357808201518184015260208101905062000146565b5f8484015250505050565b5f620001846200017e846200010f565b620000f1565b905082815260208101848484011115620001a357620001a26200007a565b5b620001b084828562000144565b509392505050565b5f82601f830112620001cf57620001ce62000076565b5b8151620001e18482602086016200016e565b91505092915050565b5f602082840312156200020257620002016200006e565b5b5f82015167ffffffffffffffff81111562000222576200022162000072565b5b6200023084828501620001b8565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200028857607f821691505b6020821081036200029e576200029d62000243565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002c5565b6200030e8683620002c5565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f62000358620003526200034c8462000326565b6200032f565b62000326565b9050919050565b5f819050919050565b620003738362000338565b6200038b62000382826200035f565b848454620002d1565b825550505050565b5f90565b620003a162000393565b620003ae81848462000368565b505050565b5b81811015620003d557620003c95f8262000397565b600181019050620003b4565b5050565b601f8211156200042457620003ee81620002a4565b620003f984620002b6565b8101602085101562000409578190505b620004216200041885620002b6565b830182620003b3565b50505b505050565b5f82821c905092915050565b5f620004465f198460080262000429565b1980831691505092915050565b5f62000460838362000435565b9150826002028217905092915050565b6200047b8262000239565b67ffffffffffffffff8111156200049757620004966200008e565b5b620004a3825462000270565b620004b0828285620003d9565b5f60209050601f831160018114620004e6575f8415620004d1578287015190505b620004dd858262000453565b8655506200054c565b601f198416620004f686620002a4565b5f5b828110156200051f57848901518255600182019150602085019450602081019050620004f8565b868310156200053f57848901516200053b601f89168262000435565b8355505b6001600288020188555050505b505050505050565b611f8980620005625f395ff3fe608060405234801561000f575f80fd5b5060043610610090575f3560e01c80634e1273f4116100645780634e1273f414610140578063731133e914610170578063a22cb4651461018c578063e985e9c5146101a8578063f242432a146101d857610090565b8062fdd58e1461009457806301ffc9a7146100c45780630e89341c146100f45780632eb2c2d614610124575b5f80fd5b6100ae60048036038101906100a991906113bd565b6101f4565b6040516100bb919061140a565b60405180910390f35b6100de60048036038101906100d99190611478565b610249565b6040516100eb91906114bd565b60405180910390f35b61010e600480360381019061010991906114d6565b61032a565b60405161011b919061158b565b60405180910390f35b61013e6004803603810190610139919061179b565b6103bc565b005b61015a60048036038101906101559190611926565b610463565b6040516101679190611a53565b60405180910390f35b61018a60048036038101906101859190611a73565b61056a565b005b6101a660048036038101906101a19190611b1d565b61057c565b005b6101c260048036038101906101bd9190611b5b565b610592565b6040516101cf91906114bd565b60405180910390f35b6101f260048036038101906101ed9190611b99565b610620565b005b5f805f8381526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f7fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061031357507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103235750610322826106c7565b5b9050919050565b60606002805461033990611c59565b80601f016020809104026020016040519081016040528092919081815260200182805461036590611c59565b80156103b05780601f10610387576101008083540402835291602001916103b0565b820191905f5260205f20905b81548152906001019060200180831161039357829003601f168201915b50505050509050919050565b5f6103c5610730565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561040a57506104088682610592565b155b1561044e5780866040517fe237d922000000000000000000000000000000000000000000000000000000008152600401610445929190611c98565b60405180910390fd5b61045b8686868686610737565b505050505050565b606081518351146104af57815183516040517f5b0599910000000000000000000000000000000000000000000000000000000081526004016104a6929190611cbf565b60405180910390fd5b5f835167ffffffffffffffff8111156104cb576104ca6115af565b5b6040519080825280602002602001820160405280156104f95781602001602082028036833780820191505090505b5090505f5b845181101561055f5761053561051d828761082b90919063ffffffff16565b610530838761083e90919063ffffffff16565b6101f4565b82828151811061054857610547611ce6565b5b6020026020010181815250508060010190506104fe565b508091505092915050565b61057684848484610851565b50505050565b61058e610587610730565b83836108e6565b5050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f610629610730565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561066e575061066c8682610592565b155b156106b25780866040517fe237d9220000000000000000000000000000000000000000000000000000000081526004016106a9929190611c98565b60405180910390fd5b6106bf8686868686610a4f565b505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036107a7575f6040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161079e9190611d13565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610817575f6040517f01a8351400000000000000000000000000000000000000000000000000000000815260040161080e9190611d13565b60405180910390fd5b6108248585858585610b55565b5050505050565b5f60208202602084010151905092915050565b5f60208202602084010151905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036108c1575f6040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016108b89190611d13565b60405180910390fd5b5f806108cd8585610c01565b915091506108de5f87848487610b55565b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610956575f6040517fced3e10000000000000000000000000000000000000000000000000000000000815260040161094d9190611d13565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610a4291906114bd565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610abf575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401610ab69190611d13565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610b2f575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401610b269190611d13565b60405180910390fd5b5f80610b3b8585610c01565b91509150610b4c8787848487610b55565b50505050505050565b610b6185858585610c31565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610bfa575f610b9d610730565b90506001845103610be9575f610bbc5f8661083e90919063ffffffff16565b90505f610bd25f8661083e90919063ffffffff16565b9050610be2838989858589610fc1565b5050610bf8565b610bf7818787878787611170565b5b505b5050505050565b60608060405191506001825283602083015260408201905060018152826020820152604081016040529250929050565b8051825114610c7b57815181516040517f5b059991000000000000000000000000000000000000000000000000000000008152600401610c72929190611cbf565b60405180910390fd5b5f610c84610730565b90505f5b8351811015610e80575f610ca5828661083e90919063ffffffff16565b90505f610cbb838661083e90919063ffffffff16565b90505f73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614610dde575f805f8481526020019081526020015f205f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015610d8a57888183856040517f03dee4c5000000000000000000000000000000000000000000000000000000008152600401610d819493929190611d2c565b60405180910390fd5b8181035f808581526020019081526020015f205f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610e7357805f808481526020019081526020015f205f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610e6b9190611d9c565b925050819055505b5050806001019050610c88565b506001835103610f3b575f610e9e5f8561083e90919063ffffffff16565b90505f610eb45f8561083e90919063ffffffff16565b90508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051610f2c929190611cbf565b60405180910390a45050610fba565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051610fb1929190611dcf565b60405180910390a45b5050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115611168578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b8152600401611021959493929190611e56565b6020604051808303815f875af192505050801561105c57506040513d601f19601f820116820180604052508101906110599190611ec2565b60015b6110dd573d805f811461108a576040519150601f19603f3d011682016040523d82523d5f602084013e61108f565b606091505b505f8151036110d557846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016110cc9190611d13565b60405180910390fd5b805181602001fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461116657846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161115d9190611d13565b60405180910390fd5b505b505050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115611317578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b81526004016111d0959493929190611eed565b6020604051808303815f875af192505050801561120b57506040513d601f19601f820116820180604052508101906112089190611ec2565b60015b61128c573d805f8114611239576040519150601f19603f3d011682016040523d82523d5f602084013e61123e565b606091505b505f81510361128457846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161127b9190611d13565b60405180910390fd5b805181602001fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461131557846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161130c9190611d13565b60405180910390fd5b505b505050505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61135982611330565b9050919050565b6113698161134f565b8114611373575f80fd5b50565b5f8135905061138481611360565b92915050565b5f819050919050565b61139c8161138a565b81146113a6575f80fd5b50565b5f813590506113b781611393565b92915050565b5f80604083850312156113d3576113d2611328565b5b5f6113e085828601611376565b92505060206113f1858286016113a9565b9150509250929050565b6114048161138a565b82525050565b5f60208201905061141d5f8301846113fb565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61145781611423565b8114611461575f80fd5b50565b5f813590506114728161144e565b92915050565b5f6020828403121561148d5761148c611328565b5b5f61149a84828501611464565b91505092915050565b5f8115159050919050565b6114b7816114a3565b82525050565b5f6020820190506114d05f8301846114ae565b92915050565b5f602082840312156114eb576114ea611328565b5b5f6114f8848285016113a9565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561153857808201518184015260208101905061151d565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61155d82611501565b611567818561150b565b935061157781856020860161151b565b61158081611543565b840191505092915050565b5f6020820190508181035f8301526115a38184611553565b905092915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6115e582611543565b810181811067ffffffffffffffff82111715611604576116036115af565b5b80604052505050565b5f61161661131f565b905061162282826115dc565b919050565b5f67ffffffffffffffff821115611641576116406115af565b5b602082029050602081019050919050565b5f80fd5b5f61166861166384611627565b61160d565b9050808382526020820190506020840283018581111561168b5761168a611652565b5b835b818110156116b457806116a088826113a9565b84526020840193505060208101905061168d565b5050509392505050565b5f82601f8301126116d2576116d16115ab565b5b81356116e2848260208601611656565b91505092915050565b5f80fd5b5f67ffffffffffffffff821115611709576117086115af565b5b61171282611543565b9050602081019050919050565b828183375f83830152505050565b5f61173f61173a846116ef565b61160d565b90508281526020810184848401111561175b5761175a6116eb565b5b61176684828561171f565b509392505050565b5f82601f830112611782576117816115ab565b5b813561179284826020860161172d565b91505092915050565b5f805f805f60a086880312156117b4576117b3611328565b5b5f6117c188828901611376565b95505060206117d288828901611376565b945050604086013567ffffffffffffffff8111156117f3576117f261132c565b5b6117ff888289016116be565b935050606086013567ffffffffffffffff8111156118205761181f61132c565b5b61182c888289016116be565b925050608086013567ffffffffffffffff81111561184d5761184c61132c565b5b6118598882890161176e565b9150509295509295909350565b5f67ffffffffffffffff8211156118805761187f6115af565b5b602082029050602081019050919050565b5f6118a361189e84611866565b61160d565b905080838252602082019050602084028301858111156118c6576118c5611652565b5b835b818110156118ef57806118db8882611376565b8452602084019350506020810190506118c8565b5050509392505050565b5f82601f83011261190d5761190c6115ab565b5b813561191d848260208601611891565b91505092915050565b5f806040838503121561193c5761193b611328565b5b5f83013567ffffffffffffffff8111156119595761195861132c565b5b611965858286016118f9565b925050602083013567ffffffffffffffff8111156119865761198561132c565b5b611992858286016116be565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6119ce8161138a565b82525050565b5f6119df83836119c5565b60208301905092915050565b5f602082019050919050565b5f611a018261199c565b611a0b81856119a6565b9350611a16836119b6565b805f5b83811015611a46578151611a2d88826119d4565b9750611a38836119eb565b925050600181019050611a19565b5085935050505092915050565b5f6020820190508181035f830152611a6b81846119f7565b905092915050565b5f805f8060808587031215611a8b57611a8a611328565b5b5f611a9887828801611376565b9450506020611aa9878288016113a9565b9350506040611aba878288016113a9565b925050606085013567ffffffffffffffff811115611adb57611ada61132c565b5b611ae78782880161176e565b91505092959194509250565b611afc816114a3565b8114611b06575f80fd5b50565b5f81359050611b1781611af3565b92915050565b5f8060408385031215611b3357611b32611328565b5b5f611b4085828601611376565b9250506020611b5185828601611b09565b9150509250929050565b5f8060408385031215611b7157611b70611328565b5b5f611b7e85828601611376565b9250506020611b8f85828601611376565b9150509250929050565b5f805f805f60a08688031215611bb257611bb1611328565b5b5f611bbf88828901611376565b9550506020611bd088828901611376565b9450506040611be1888289016113a9565b9350506060611bf2888289016113a9565b925050608086013567ffffffffffffffff811115611c1357611c1261132c565b5b611c1f8882890161176e565b9150509295509295909350565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611c7057607f821691505b602082108103611c8357611c82611c2c565b5b50919050565b611c928161134f565b82525050565b5f604082019050611cab5f830185611c89565b611cb86020830184611c89565b9392505050565b5f604082019050611cd25f8301856113fb565b611cdf60208301846113fb565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f602082019050611d265f830184611c89565b92915050565b5f608082019050611d3f5f830187611c89565b611d4c60208301866113fb565b611d5960408301856113fb565b611d6660608301846113fb565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611da68261138a565b9150611db18361138a565b9250828201905080821115611dc957611dc8611d6f565b5b92915050565b5f6040820190508181035f830152611de781856119f7565b90508181036020830152611dfb81846119f7565b90509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f611e2882611e04565b611e328185611e0e565b9350611e4281856020860161151b565b611e4b81611543565b840191505092915050565b5f60a082019050611e695f830188611c89565b611e766020830187611c89565b611e8360408301866113fb565b611e9060608301856113fb565b8181036080830152611ea28184611e1e565b90509695505050505050565b5f81519050611ebc8161144e565b92915050565b5f60208284031215611ed757611ed6611328565b5b5f611ee484828501611eae565b91505092915050565b5f60a082019050611f005f830188611c89565b611f0d6020830187611c89565b8181036040830152611f1f81866119f7565b90508181036060830152611f3381856119f7565b90508181036080830152611f478184611e1e565b9050969550505050505056fea26469706673582212203835581c6344b12728c44fa4d9e912cd60e64012c1b772bb703d1c36825c16fd64736f6c63430008180033"; pub const NFT_SWAP_CONTRACT_BYTES: &str = "60a060405234801562000010575f80fd5b50604051620055a2380380620055a2833981810160405281019062000036919062000147565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200009e90620001fb565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506200021b565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200011182620000e6565b9050919050565b620001238162000105565b81146200012e575f80fd5b50565b5f81519050620001418162000118565b92915050565b5f602082840312156200015f576200015e620000e2565b5b5f6200016e8482850162000131565b91505092915050565b5f82825260208201905092915050565b7f66656541646472657373206d757374206e6f74206265207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f620001e360238362000177565b9150620001f08262000187565b604082019050919050565b5f6020820190508181035f8301526200021481620001d5565b9050919050565b608051615360620002425f395f8181612aef01528181612b8a0152612f4801526153605ff3fe608060405260043610610113575f3560e01c80639b4603f21161009f578063cc90c19911610063578063cc90c1991461038e578063d6a71eb4146103b6578063e06cf966146103de578063efccb9eb14610408578063f23a6e611461044657610113565b80639b4603f2146102be578063b27e46fb146102da578063bc197c8114610302578063c8d9009b1461033e578063c92cd12d1461036657610113565b8063150b7a02116100e6578063150b7a02146101cb5780633e6af5f21461020757806346b95ac71461022f57806365e266171461026e5780636e6bf6d21461029657610113565b806301ffc9a71461011757806305ec158d146101535780630f235fce1461017b578063146e5b24146101a3575b5f80fd5b348015610122575f80fd5b5061013d6004803603810190610138919061386f565b610482565b60405161014a91906138b4565b60405180910390f35b34801561015e575f80fd5b506101796004803603810190610174919061398d565b610563565b005b348015610186575f80fd5b506101a1600480360381019061019c9190613a2a565b610823565b005b3480156101ae575f80fd5b506101c960048036038101906101c49190613ab3565b610add565b005b3480156101d6575f80fd5b506101f160048036038101906101ec9190613bb1565b610cc3565b6040516101fe9190613c44565b60405180910390f35b348015610212575f80fd5b5061022d60048036038101906102289190613ab3565b611112565b005b34801561023a575f80fd5b5061025560048036038101906102509190613c5d565b611423565b6040516102659493929190613d53565b60405180910390f35b348015610279575f80fd5b50610294600480360381019061028f9190613ab3565b611485565b005b3480156102a1575f80fd5b506102bc60048036038101906102b79190613a2a565b6118e9565b005b6102d860048036038101906102d39190613dc0565b611ba4565b005b3480156102e5575f80fd5b5061030060048036038101906102fb919061398d565b611eda565b005b34801561030d575f80fd5b5061032860048036038101906103239190613eb2565b612199565b6040516103359190613c44565b60405180910390f35b348015610349575f80fd5b50610364600480360381019061035f9190613a2a565b6121d5565b005b348015610371575f80fd5b5061038c6004803603810190610387919061398d565b6124fe565b005b348015610399575f80fd5b506103b460048036038101906103af9190613ab3565b61282c565b005b3480156103c1575f80fd5b506103dc60048036038101906103d79190613f89565b612bdc565b005b3480156103e9575f80fd5b506103f2612f46565b6040516103ff919061405c565b60405180910390f35b348015610413575f80fd5b5061042e60048036038101906104299190613c5d565b612f6a565b60405161043d939291906140bb565b60405180910390f35b348015610451575f80fd5b5061046c600480360381019061046791906140f0565b612fb6565b6040516104799190613c44565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061054c57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061055c575061055b8261344a565b5b9050919050565b6001600381111561057757610576613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff1660038111156105a9576105a8613ce0565b5b146105e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e090614206565b60405180910390fd5b5f600387336002896040516020016106019190614244565b60405160208183030381529060405260405161061d91906142ca565b602060405180830381855afa158015610638573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065b91906142f4565b888888886040516020016106759796959493929190614384565b60405160208183030381529060405260405161069191906142ca565b602060405180830381855afa1580156106ac573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610736576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072d9061444e565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561076c5761076b613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd73886040516107a0919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016107eb94939291906144d6565b5f604051808303815f87803b158015610802575f80fd5b505af1158015610814573d5f803e3d5ffd5b50505050505050505050505050565b6001600381111561083757610836613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561086957610868613ce0565b5b146108a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a090614206565b60405180910390fd5b5f60038633878787876040516020016108c79695949392919061452c565b6040516020818303038152906040526040516108e391906142ca565b602060405180830381855afa1580156108fe573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097f9061444e565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156109f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ea9061460b565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610a2957610a28613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907287604051610a5d919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610aa693929190614629565b5f604051808303815f87803b158015610abd575f80fd5b505af1158015610acf573d5f803e3d5ffd5b505050505050505050505050565b60016004811115610af157610af0613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115610b2457610b23613ce0565b5b14610b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5b90614206565b60405180910390fd5b5f600387878733888888604051602001610b84979695949392919061465e565b604051602081830303815290604052604051610ba091906142ca565b602060405180830381855afa158015610bbb573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610c46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3d9061444e565b60405180910390fd5b600260015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610c7d57610c7c613ce0565b5b02179055507f9c45e43e2ef051f70491ffd5221bf02ab37e1324128714ef9610df5f24fc9fb588604051610cb1919061447b565b60405180910390a15050505050505050565b5f808383810190610cd49190614807565b90505f6003811115610ce957610ce8613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff166003811115610d1e57610d1d613ce0565b5b14610d5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d55906148a2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603610dd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc79061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610e42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3990614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610eb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eab90614a00565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610f22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1990614a68565b60405180910390fd5b610f2f81602001516134b3565b15610f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6690614ad0565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610f9d9695949392919061452c565b604051602081830303815290604052604051610fb991906142ca565b602060405180830381855afa158015610fd4573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561102457611023613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156110bb576110ba613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f01516040516110f5919061447b565b60405180910390a163150b7a0260e01b9250505095945050505050565b6001600481111561112657611125613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561115957611158613ce0565b5b14611199576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119090614206565b60405180910390fd5b5f6003878787336002896040516020016111b39190614244565b6040516020818303038152906040526040516111cf91906142ca565b602060405180830381855afa1580156111ea573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061120d91906142f4565b8888604051602001611225979695949392919061465e565b60405160208183030381529060405260405161124191906142ca565b602060405180830381855afa15801561125c573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146112e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112de9061444e565b60405180910390fd5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff0219169083600481111561131e5761131d613ce0565b5b02179055507f45169a52eef651b20a81474b50b8a5d83225225fcd097ef3cf7952d9ab304f278885604051611354929190614aee565b60405180910390a15f86886113699190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113e7573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156113e1573d5f803e3d5ffd5b50611418565b5f83905061141633838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b6001602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900463ffffffff1690805f01601c9054906101000a900460ff16905084565b6001600481111561149957611498613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff1660048111156114cc576114cb613ce0565b5b148061151c5750600260048111156114e7576114e6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561151a57611519613ce0565b5b145b61155b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155290614be5565b60405180910390fd5b5f60038787873388888860405160200161157b979695949392919061465e565b60405160208183030381529060405260405161159791906142ca565b602060405180830381855afa1580156115b2573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461163d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116349061444e565b60405180910390fd5b6002600481111561165157611650613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561168457611683613ce0565b5b036116f65760015f8981526020019081526020015f205f0160189054906101000a900463ffffffff1663ffffffff164210156116f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ec9061460b565b60405180910390fd5b5b6001600481111561170a57611709613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561173d5761173c613ce0565b5b036117af5760015f8981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156117ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a590614c73565b60405180910390fd5b5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156117e6576117e5613ce0565b5b02179055507fbdd7a4be6d82798a500b59077706b12d3f45acf5504828919f92501307b2b9538860405161181a919061447b565b60405180910390a15f868861182f9190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118ad573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156118a7573d5f803e3d5ffd5b506118de565b5f8390506118dc33838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b600160038111156118fd576118fc613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561192f5761192e613ce0565b5b1461196f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196690614206565b60405180910390fd5b5f600386336002886040516020016119879190614244565b6040516020818303038152906040526040516119a391906142ca565b602060405180830381855afa1580156119be573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906119e191906142f4565b8787876040516020016119f99695949392919061452c565b604051602081830303815290604052604051611a1591906142ca565b602060405180830381855afa158015611a30573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611aba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab19061444e565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115611af057611aef613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051611b24919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401611b6d93929190614629565b5f604051808303815f87803b158015611b84575f80fd5b505af1158015611b96573d5f803e3d5ffd5b505050505050505050505050565b5f6004811115611bb757611bb6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115611bea57611be9613ce0565b5b14611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2190614d01565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611c98576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8f90614d8f565b60405180910390fd5b5f3411611cda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd190614e1d565b60405180910390fd5b853411611d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1390614eab565b60405180910390fd5b5f60038734611d2b9190614ec9565b88883389895f604051602001611d47979695949392919061465e565b604051602081830303815290604052604051611d6391906142ca565b602060405180830381855afa158015611d7e573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115611dd657611dd5613ce0565b5b81525060015f8a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115611e9157611e90613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd93588604051611ec8919061447b565b60405180910390a15050505050505050565b60016003811115611eee57611eed613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115611f2057611f1f613ce0565b5b14611f60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5790614206565b60405180910390fd5b5f600387338888888888604051602001611f809796959493929190614384565b604051602081830303815290604052604051611f9c91906142ca565b602060405180830381855afa158015611fb7573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612041576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120389061444e565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156120ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a39061460b565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156120e2576120e1613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907288604051612116919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161216194939291906144d6565b5f604051808303815f87803b158015612178575f80fd5b505af115801561218a573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121cc90614f46565b60405180910390fd5b600160038111156121e9576121e8613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561221b5761221a613ce0565b5b1461225b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161225290614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c090614fae565b60405180910390fd5b5f60033387876002886040516020016122e29190614244565b6040516020818303038152906040526040516122fe91906142ca565b602060405180830381855afa158015612319573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061233c91906142f4565b87876040516020016123539695949392919061452c565b60405160208183030381529060405260405161236f91906142ca565b602060405180830381855afa15801561238a573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612414576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240b9061444e565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561244a57612449613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161247e919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016124c793929190614629565b5f604051808303815f87803b1580156124de575f80fd5b505af11580156124f0573d5f803e3d5ffd5b505050505050505050505050565b6001600381111561251257612511613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561254457612543613ce0565b5b14612584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257b90614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146125f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125e990614fae565b60405180910390fd5b5f600333888860028960405160200161260b9190614244565b60405160208183030381529060405260405161262791906142ca565b602060405180830381855afa158015612642573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061266591906142f4565b88888860405160200161267e9796959493929190614384565b60405160208183030381529060405260405161269a91906142ca565b602060405180830381855afa1580156126b5573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461273f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127369061444e565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561277557612774613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0886040516127a9919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016127f494939291906144d6565b5f604051808303815f87803b15801561280b575f80fd5b505af115801561281d573d5f803e3d5ffd5b50505050505050505050505050565b600260048111156128405761283f613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561287357612872613ce0565b5b146128b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128aa9061503c565b60405180910390fd5b5f600387873388886002896040516020016128ce9190614244565b6040516020818303038152906040526040516128ea91906142ca565b602060405180830381855afa158015612905573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061292891906142f4565b8860405160200161293f979695949392919061465e565b60405160208183030381529060405260405161295b91906142ca565b602060405180830381855afa158015612976573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612a01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129f89061444e565b60405180910390fd5b600360015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115612a3857612a37613ce0565b5b02179055507f0d0da0df275f85bed3a5fe7ae79f3559341a3f9ccd8e010133438135bda00a878884604051612a6e929190614aee565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612b56573373ffffffffffffffffffffffffffffffffffffffff166108fc8890811502906040515f60405180830381858888f19350505050158015612aec573d5f803e3d5ffd5b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f19350505050158015612b50573d5f803e3d5ffd5b50612bd2565b5f829050612b8533898373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b612bd07f0000000000000000000000000000000000000000000000000000000000000000888373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b5050505050505050565b5f6004811115612bef57612bee613ce0565b5b60015f8b81526020019081526020015f205f01601c9054906101000a900460ff166004811115612c2257612c21613ce0565b5b14612c62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c59906150ca565b60405180910390fd5b5f8811612ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c9b90615132565b60405180910390fd5b5f8711612ce6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cdd9061519a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612d54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d4b90614d8f565b60405180910390fd5b5f60038989883389898d604051602001612d74979695949392919061465e565b604051602081830303815290604052604051612d9091906142ca565b602060405180830381855afa158015612dab573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115612e0357612e02613ce0565b5b81525060015f8c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115612ebe57612ebd613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358a604051612ef5919061447b565b60405180910390a15f879050612f3933308b8d612f129190614b42565b8473ffffffffffffffffffffffffffffffffffffffff16613543909392919063ffffffff16565b5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f808383810190612fc79190614807565b90505f6003811115612fdc57612fdb613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff16600381111561301157613010613ce0565b5b14613051576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161304890615228565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff16036130c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130ba9061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161312c90614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146131a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161319e90614a00565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614613215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161320c90614a68565b60405180910390fd5b5f8511613257576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161324e90615290565b60405180910390fd5b61326481602001516134b3565b156132a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161329b90614ad0565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c6040516020016132d49796959493929190614384565b6040516020818303038152906040526040516132f091906142ca565b602060405180830381855afa15801561330b573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561335b5761335a613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156133f2576133f1613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f015160405161342c919061447b565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b61353e838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85856040516024016134f79291906152ae565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b505050565b6135bf848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161357893929190614629565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b50505050565b5f6135ef828473ffffffffffffffffffffffffffffffffffffffff1661365a90919063ffffffff16565b90505f81511415801561361357508080602001905181019061361191906152ff565b155b1561365557826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161364c919061405c565b60405180910390fd5b505050565b606061366783835f61366f565b905092915050565b6060814710156136b657306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016136ad919061405c565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516136de91906142ca565b5f6040518083038185875af1925050503d805f8114613718576040519150601f19603f3d011682016040523d82523d5f602084013e61371d565b606091505b509150915061372d868383613738565b925050509392505050565b60608261374d57613748826137c5565b6137bd565b5f825114801561377357505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156137b557836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016137ac919061405c565b60405180910390fd5b8190506137be565b5b9392505050565b5f815111156137d75780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61384e8161381a565b8114613858575f80fd5b50565b5f8135905061386981613845565b92915050565b5f6020828403121561388457613883613812565b5b5f6138918482850161385b565b91505092915050565b5f8115159050919050565b6138ae8161389a565b82525050565b5f6020820190506138c75f8301846138a5565b92915050565b5f819050919050565b6138df816138cd565b81146138e9575f80fd5b50565b5f813590506138fa816138d6565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61392982613900565b9050919050565b6139398161391f565b8114613943575f80fd5b50565b5f8135905061395481613930565b92915050565b5f819050919050565b61396c8161395a565b8114613976575f80fd5b50565b5f8135905061398781613963565b92915050565b5f805f805f805f60e0888a0312156139a8576139a7613812565b5b5f6139b58a828b016138ec565b97505060206139c68a828b01613946565b96505060406139d78a828b016138ec565b95505060606139e88a828b016138ec565b94505060806139f98a828b01613946565b93505060a0613a0a8a828b01613979565b92505060c0613a1b8a828b01613979565b91505092959891949750929550565b5f805f805f8060c08789031215613a4457613a43613812565b5b5f613a5189828a016138ec565b9650506020613a6289828a01613946565b9550506040613a7389828a016138ec565b9450506060613a8489828a016138ec565b9350506080613a9589828a01613946565b92505060a0613aa689828a01613979565b9150509295509295509295565b5f805f805f805f60e0888a031215613ace57613acd613812565b5b5f613adb8a828b016138ec565b9750506020613aec8a828b01613979565b9650506040613afd8a828b01613979565b9550506060613b0e8a828b01613946565b9450506080613b1f8a828b016138ec565b93505060a0613b308a828b016138ec565b92505060c0613b418a828b01613946565b91505092959891949750929550565b5f80fd5b5f80fd5b5f80fd5b5f8083601f840112613b7157613b70613b50565b5b8235905067ffffffffffffffff811115613b8e57613b8d613b54565b5b602083019150836001820283011115613baa57613ba9613b58565b5b9250929050565b5f805f805f60808688031215613bca57613bc9613812565b5b5f613bd788828901613946565b9550506020613be888828901613946565b9450506040613bf988828901613979565b935050606086013567ffffffffffffffff811115613c1a57613c19613816565b5b613c2688828901613b5c565b92509250509295509295909350565b613c3e8161381a565b82525050565b5f602082019050613c575f830184613c35565b92915050565b5f60208284031215613c7257613c71613812565b5b5f613c7f848285016138ec565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b613cbc81613c88565b82525050565b5f63ffffffff82169050919050565b613cda81613cc2565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60058110613d1e57613d1d613ce0565b5b50565b5f819050613d2e82613d0d565b919050565b5f613d3d82613d21565b9050919050565b613d4d81613d33565b82525050565b5f608082019050613d665f830187613cb3565b613d736020830186613cd1565b613d806040830185613cd1565b613d8d6060830184613d44565b95945050505050565b613d9f81613cc2565b8114613da9575f80fd5b50565b5f81359050613dba81613d96565b92915050565b5f805f805f805f60e0888a031215613ddb57613dda613812565b5b5f613de88a828b016138ec565b9750506020613df98a828b01613979565b9650506040613e0a8a828b01613946565b9550506060613e1b8a828b016138ec565b9450506080613e2c8a828b016138ec565b93505060a0613e3d8a828b01613dac565b92505060c0613e4e8a828b01613dac565b91505092959891949750929550565b5f8083601f840112613e7257613e71613b50565b5b8235905067ffffffffffffffff811115613e8f57613e8e613b54565b5b602083019150836020820283011115613eab57613eaa613b58565b5b9250929050565b5f805f805f805f8060a0898b031215613ece57613ecd613812565b5b5f613edb8b828c01613946565b9850506020613eec8b828c01613946565b975050604089013567ffffffffffffffff811115613f0d57613f0c613816565b5b613f198b828c01613e5d565b9650965050606089013567ffffffffffffffff811115613f3c57613f3b613816565b5b613f488b828c01613e5d565b9450945050608089013567ffffffffffffffff811115613f6b57613f6a613816565b5b613f778b828c01613b5c565b92509250509295985092959890939650565b5f805f805f805f805f6101208a8c031215613fa757613fa6613812565b5b5f613fb48c828d016138ec565b9950506020613fc58c828d01613979565b9850506040613fd68c828d01613979565b9750506060613fe78c828d01613946565b9650506080613ff88c828d01613946565b95505060a06140098c828d016138ec565b94505060c061401a8c828d016138ec565b93505060e061402b8c828d01613dac565b92505061010061403d8c828d01613dac565b9150509295985092959850929598565b6140568161391f565b82525050565b5f60208201905061406f5f83018461404d565b92915050565b6004811061408657614085613ce0565b5b50565b5f81905061409682614075565b919050565b5f6140a582614089565b9050919050565b6140b58161409b565b82525050565b5f6060820190506140ce5f830186613cb3565b6140db6020830185613cd1565b6140e860408301846140ac565b949350505050565b5f805f805f8060a0878903121561410a57614109613812565b5b5f61411789828a01613946565b965050602061412889828a01613946565b955050604061413989828a01613979565b945050606061414a89828a01613979565b935050608087013567ffffffffffffffff81111561416b5761416a613816565b5b61417789828a01613b5c565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f6141f0602a83614186565b91506141fb82614196565b604082019050919050565b5f6020820190508181035f83015261421d816141e4565b9050919050565b5f819050919050565b61423e614239826138cd565b614224565b82525050565b5f61424f828461422d565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b5f5b8381101561428f578082015181840152602081019050614274565b5f8484015250505050565b5f6142a48261425e565b6142ae8185614268565b93506142be818560208601614272565b80840191505092915050565b5f6142d5828461429a565b915081905092915050565b5f815190506142ee816138d6565b92915050565b5f6020828403121561430957614308613812565b5b5f614316848285016142e0565b91505092915050565b5f8160601b9050919050565b5f6143358261431f565b9050919050565b5f6143468261432b565b9050919050565b61435e6143598261391f565b61433c565b82525050565b5f819050919050565b61437e6143798261395a565b614364565b82525050565b5f61438f828a61434d565b60148201915061439f828961434d565b6014820191506143af828861422d565b6020820191506143bf828761422d565b6020820191506143cf828661434d565b6014820191506143df828561436d565b6020820191506143ef828461436d565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f614438601383614186565b915061444382614404565b602082019050919050565b5f6020820190508181035f8301526144658161442c565b9050919050565b614475816138cd565b82525050565b5f60208201905061448e5f83018461446c565b92915050565b61449d8161395a565b82525050565b5f82825260208201905092915050565b50565b5f6144c15f836144a3565b91506144cc826144b3565b5f82019050919050565b5f60a0820190506144e95f83018761404d565b6144f6602083018661404d565b6145036040830185614494565b6145106060830184614494565b8181036080830152614521816144b6565b905095945050505050565b5f614537828961434d565b601482019150614547828861434d565b601482019150614557828761422d565b602082019150614567828661422d565b602082019150614577828561434d565b601482019150614587828461436d565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f6145f5603883614186565b91506146008261459b565b604082019050919050565b5f6020820190508181035f830152614622816145e9565b9050919050565b5f60608201905061463c5f83018661404d565b614649602083018561404d565b6146566040830184614494565b949350505050565b5f614669828a61436d565b602082019150614679828961436d565b602082019150614689828861434d565b601482019150614699828761434d565b6014820191506146a9828661422d565b6020820191506146b9828561422d565b6020820191506146c9828461434d565b60148201915081905098975050505050505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b614728826146e2565b810181811067ffffffffffffffff82111715614747576147466146f2565b5b80604052505050565b5f614759613809565b9050614765828261471f565b919050565b5f60c0828403121561477f5761477e6146de565b5b61478960c0614750565b90505f614798848285016138ec565b5f8301525060206147ab84828501613946565b60208301525060406147bf84828501613946565b60408301525060606147d3848285016138ec565b60608301525060806147e7848285016138ec565b60808301525060a06147fb84828501613dac565b60a08301525092915050565b5f60c0828403121561481c5761481b613812565b5b5f6148298482850161476a565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f61488c602a83614186565b915061489782614832565b604082019050919050565b5f6020820190508181035f8301526148b981614880565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f6148f4601e83614186565b91506148ff826148c0565b602082019050919050565b5f6020820190508181035f830152614921816148e8565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f61495c601e83614186565b915061496782614928565b602082019050919050565b5f6020820190508181035f83015261498981614950565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f6149ea602383614186565b91506149f582614990565b604082019050919050565b5f6020820190508181035f830152614a17816149de565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f614a52601b83614186565b9150614a5d82614a1e565b602082019050919050565b5f6020820190508181035f830152614a7f81614a46565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f614aba601a83614186565b9150614ac582614a86565b602082019050919050565b5f6020820190508181035f830152614ae781614aae565b9050919050565b5f604082019050614b015f83018561446c565b614b0e602083018461446c565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614b4c8261395a565b9150614b578361395a565b9250828201905080821115614b6f57614b6e614b15565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e74206f722054616b6572417070726f7665640000000000602082015250565b5f614bcf603b83614186565b9150614bda82614b75565b604082019050919050565b5f6020820190508181035f830152614bfc81614bc3565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e74207072652d617070726f7665206c6f636b2074696d65000000602082015250565b5f614c5d603d83614186565b9150614c6882614c03565b604082019050919050565b5f6020820190508181035f830152614c8a81614c51565b9050919050565b7f54616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f614ceb602483614186565b9150614cf682614c91565b604082019050919050565b5f6020820190508181035f830152614d1881614cdf565b9050919050565b7f5265636569766572206d757374206e6f74206265207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f614d79602183614186565b9150614d8482614d1f565b604082019050919050565b5f6020820190508181035f830152614da681614d6d565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f614e07602383614186565b9150614e1282614dad565b604082019050919050565b5f6020820190508181035f830152614e3481614dfb565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e20645f8201527f6578206665650000000000000000000000000000000000000000000000000000602082015250565b5f614e95602683614186565b9150614ea082614e3b565b604082019050919050565b5f6020820190508181035f830152614ec281614e89565b9050919050565b5f614ed38261395a565b9150614ede8361395a565b9250828203905081811115614ef657614ef5614b15565b5b92915050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f614f30601d83614186565b9150614f3b82614efc565b602082019050919050565b5f6020820190508181035f830152614f5d81614f24565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f614f98601583614186565b9150614fa382614f64565b602082019050919050565b5f6020820190508181035f830152614fc581614f8c565b9050919050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520545f8201527f616b6572417070726f7665640000000000000000000000000000000000000000602082015250565b5f615026602c83614186565b915061503182614fcc565b604082019050919050565b5f6020820190508181035f8301526150538161501a565b9050919050565b7f4552433230207632207061796d656e7420697320616c726561647920696e69745f8201527f69616c697a656400000000000000000000000000000000000000000000000000602082015250565b5f6150b4602783614186565b91506150bf8261505a565b604082019050919050565b5f6020820190508181035f8301526150e1816150a8565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f61511c601783614186565b9150615127826150e8565b602082019050919050565b5f6020820190508181035f83015261514981615110565b9050919050565b7f44657820666565206d757374206e6f74206265207a65726f00000000000000005f82015250565b5f615184601883614186565b915061518f82615150565b602082019050919050565b5f6020820190508181035f8301526151b181615178565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f615212602b83614186565b915061521d826151b8565b604082019050919050565b5f6020820190508181035f83015261523f81615206565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f61527a601c83614186565b915061528582615246565b602082019050919050565b5f6020820190508181035f8301526152a78161526e565b9050919050565b5f6040820190506152c15f83018561404d565b6152ce6020830184614494565b9392505050565b6152de8161389a565b81146152e8575f80fd5b50565b5f815190506152f9816152d5565b92915050565b5f6020828403121561531457615313613812565b5b5f615321848285016152eb565b9150509291505056fea26469706673582212200d86b0f6898fb823c55626c3b02a7098bc8622606b092e0f458df6c86ce2967864736f6c63430008180033"; +// https://github.com/KomodoPlatform/etomic-swap/blob/006e6fd52334530f23624a2139d0eb5299c4cd10/contracts/EtomicSwapMakerNftV2Test.sol pub const NFT_MAKER_SWAP_V2_BYTES: &str = "6080604052348015600e575f80fd5b506131fa8061001c5f395ff3fe608060405234801561000f575f80fd5b50600436106100cd575f3560e01c8063bc197c811161008a578063eb4ab61211610064578063eb4ab61214610209578063efccb9eb14610225578063f0e9fcd114610257578063f23a6e6114610273576100cd565b8063bc197c81146101a1578063c8d9009b146101d1578063c92cd12d146101ed576100cd565b806301ffc9a7146100d157806305ec158d146101015780630f235fce1461011d578063150b7a02146101395780636e6bf6d214610169578063b27e46fb14610185575b5f80fd5b6100eb60048036038101906100e69190612005565b6102a3565b6040516100f8919061204a565b60405180910390f35b61011b60048036038101906101169190612123565b610384565b005b610137600480360381019061013291906121c0565b610644565b005b610153600480360381019061014e91906122aa565b6108fe565b604051610160919061233d565b60405180910390f35b610183600480360381019061017e91906121c0565b610d4d565b005b61019f600480360381019061019a9190612123565b611008565b005b6101bb60048036038101906101b691906123ab565b6112c7565b6040516101c8919061233d565b60405180910390f35b6101eb60048036038101906101e691906121c0565b611303565b005b61020760048036038101906102029190612123565b61162c565b005b610223600480360381019061021e9190612482565b61195a565b005b61023f600480360381019061023a91906124e6565b6119d1565b60405161024e939291906125dc565b60405180910390f35b610271600480360381019061026c9190612611565b611a1d565b005b61028d60048036038101906102889190612661565b611a91565b60405161029a919061233d565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061036d57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061037d575061037c82611f25565b5b9050919050565b6001600381111561039857610397612569565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff1660038111156103ca576103c9612569565b5b1461040a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161040190612777565b60405180910390fd5b5f6003873360028960405160200161042291906127b5565b60405160208183030381529060405260405161043e9190612821565b602060405180830381855afa158015610459573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061047c919061284b565b8888888860405160200161049697969594939291906128db565b6040516020818303038152906040526040516104b29190612821565b602060405180830381855afa1580156104cd573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610557576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161054e906129a5565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561058d5761058c612569565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd73886040516105c191906129d2565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161060c9493929190612a3c565b5f604051808303815f87803b158015610623575f80fd5b505af1158015610635573d5f803e3d5ffd5b50505050505050505050505050565b6001600381111561065857610657612569565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561068a57610689612569565b5b146106ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c190612777565b60405180910390fd5b5f60038633878787876040516020016106e896959493929190612a92565b6040516020818303038152906040526040516107049190612821565b602060405180830381855afa15801561071f573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146107a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107a0906129a5565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610814576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161080b90612b71565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561084a57610849612569565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad192190728760405161087e91906129d2565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016108c793929190612b8f565b5f604051808303815f87803b1580156108de575f80fd5b505af11580156108f0573d5f803e3d5ffd5b505050505050505050505050565b5f80838381019061090f9190612d17565b90505f600381111561092457610923612569565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff16600381111561095957610958612569565b5b14610999576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099090612db2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603610a0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0290612e1a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610a7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7490612e82565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610aef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae690612f10565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610b5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5490612f78565b60405180910390fd5b610b6a8160200151611f8e565b15610baa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba190612fe0565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610bd896959493929190612a92565b604051602081830303815290604052604051610bf49190612821565b602060405180830381855afa158015610c0f573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115610c5f57610c5e612569565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115610cf657610cf5612569565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051610d3091906129d2565b60405180910390a163150b7a0260e01b9250505095945050505050565b60016003811115610d6157610d60612569565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff166003811115610d9357610d92612569565b5b14610dd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dca90612777565b60405180910390fd5b5f60038633600288604051602001610deb91906127b5565b604051602081830303815290604052604051610e079190612821565b602060405180830381855afa158015610e22573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610e45919061284b565b878787604051602001610e5d96959493929190612a92565b604051602081830303815290604052604051610e799190612821565b602060405180830381855afa158015610e94573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610f1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f15906129a5565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610f5457610f53612569565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051610f8891906129d2565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610fd193929190612b8f565b5f604051808303815f87803b158015610fe8575f80fd5b505af1158015610ffa573d5f803e3d5ffd5b505050505050505050505050565b6001600381111561101c5761101b612569565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561104e5761104d612569565b5b1461108e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108590612777565b60405180910390fd5b5f6003873388888888886040516020016110ae97969594939291906128db565b6040516020818303038152906040526040516110ca9190612821565b602060405180830381855afa1580156110e5573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461116f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611166906129a5565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156111da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d190612b71565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156112105761120f612569565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad192190728860405161124491906129d2565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161128f9493929190612a3c565b5f604051808303815f87803b1580156112a6575f80fd5b505af11580156112b8573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112fa90613048565b60405180910390fd5b6001600381111561131757611316612569565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561134957611348612569565b5b14611389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138090612777565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ee906130b0565b60405180910390fd5b5f600333878760028860405160200161141091906127b5565b60405160208183030381529060405260405161142c9190612821565b602060405180830381855afa158015611447573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061146a919061284b565b878760405160200161148196959493929190612a92565b60405160208183030381529060405260405161149d9190612821565b602060405180830381855afa1580156114b8573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611542576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611539906129a5565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561157857611577612569565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0876040516115ac91906129d2565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016115f593929190612b8f565b5f604051808303815f87803b15801561160c575f80fd5b505af115801561161e573d5f803e3d5ffd5b505050505050505050505050565b600160038111156116405761163f612569565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561167257611671612569565b5b146116b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a990612777565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611720576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611717906130b0565b60405180910390fd5b5f600333888860028960405160200161173991906127b5565b6040516020818303038152906040526040516117559190612821565b602060405180830381855afa158015611770573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190611793919061284b565b8888886040516020016117ac97969594939291906128db565b6040516020818303038152906040526040516117c89190612821565b602060405180830381855afa1580156117e3573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461186d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611864906129a5565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156118a3576118a2612569565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0886040516118d791906129d2565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016119229493929190612a3c565b5f604051808303815f87803b158015611939575f80fd5b505af115801561194b573d5f803e3d5ffd5b50505050505050505050505050565b5f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a308487876040518563ffffffff1660e01b815260040161199d9493929190612a3c565b5f604051808303815f87803b1580156119b4575f80fd5b505af11580156119c6573d5f803e3d5ffd5b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3084866040518463ffffffff1660e01b8152600401611a5e93929190612b8f565b5f604051808303815f87803b158015611a75575f80fd5b505af1158015611a87573d5f803e3d5ffd5b5050505050505050565b5f808383810190611aa29190612d17565b90505f6003811115611ab757611ab6612569565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff166003811115611aec57611aeb612569565b5b14611b2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b239061313e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603611b9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9590612e1a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603611c10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c0790612e82565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7990612f10565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614611cf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce790612f78565b60405180910390fd5b5f8511611d32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d29906131a6565b60405180910390fd5b611d3f8160200151611f8e565b15611d7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7690612fe0565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c604051602001611daf97969594939291906128db565b604051602081830303815290604052604051611dcb9190612821565b602060405180830381855afa158015611de6573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115611e3657611e35612569565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115611ecd57611ecc612569565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051611f0791906129d2565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611fe481611fb0565b8114611fee575f80fd5b50565b5f81359050611fff81611fdb565b92915050565b5f6020828403121561201a57612019611fa8565b5b5f61202784828501611ff1565b91505092915050565b5f8115159050919050565b61204481612030565b82525050565b5f60208201905061205d5f83018461203b565b92915050565b5f819050919050565b61207581612063565b811461207f575f80fd5b50565b5f813590506120908161206c565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6120bf82612096565b9050919050565b6120cf816120b5565b81146120d9575f80fd5b50565b5f813590506120ea816120c6565b92915050565b5f819050919050565b612102816120f0565b811461210c575f80fd5b50565b5f8135905061211d816120f9565b92915050565b5f805f805f805f60e0888a03121561213e5761213d611fa8565b5b5f61214b8a828b01612082565b975050602061215c8a828b016120dc565b965050604061216d8a828b01612082565b955050606061217e8a828b01612082565b945050608061218f8a828b016120dc565b93505060a06121a08a828b0161210f565b92505060c06121b18a828b0161210f565b91505092959891949750929550565b5f805f805f8060c087890312156121da576121d9611fa8565b5b5f6121e789828a01612082565b96505060206121f889828a016120dc565b955050604061220989828a01612082565b945050606061221a89828a01612082565b935050608061222b89828a016120dc565b92505060a061223c89828a0161210f565b9150509295509295509295565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261226a57612269612249565b5b8235905067ffffffffffffffff8111156122875761228661224d565b5b6020830191508360018202830111156122a3576122a2612251565b5b9250929050565b5f805f805f608086880312156122c3576122c2611fa8565b5b5f6122d0888289016120dc565b95505060206122e1888289016120dc565b94505060406122f28882890161210f565b935050606086013567ffffffffffffffff81111561231357612312611fac565b5b61231f88828901612255565b92509250509295509295909350565b61233781611fb0565b82525050565b5f6020820190506123505f83018461232e565b92915050565b5f8083601f84011261236b5761236a612249565b5b8235905067ffffffffffffffff8111156123885761238761224d565b5b6020830191508360208202830111156123a4576123a3612251565b5b9250929050565b5f805f805f805f8060a0898b0312156123c7576123c6611fa8565b5b5f6123d48b828c016120dc565b98505060206123e58b828c016120dc565b975050604089013567ffffffffffffffff81111561240657612405611fac565b5b6124128b828c01612356565b9650965050606089013567ffffffffffffffff81111561243557612434611fac565b5b6124418b828c01612356565b9450945050608089013567ffffffffffffffff81111561246457612463611fac565b5b6124708b828c01612255565b92509250509295985092959890939650565b5f805f806080858703121561249a57612499611fa8565b5b5f6124a7878288016120dc565b94505060206124b88782880161210f565b93505060406124c98782880161210f565b92505060606124da878288016120dc565b91505092959194509250565b5f602082840312156124fb576124fa611fa8565b5b5f61250884828501612082565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b61254581612511565b82525050565b5f63ffffffff82169050919050565b6125638161254b565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600481106125a7576125a6612569565b5b50565b5f8190506125b782612596565b919050565b5f6125c6826125aa565b9050919050565b6125d6816125bc565b82525050565b5f6060820190506125ef5f83018661253c565b6125fc602083018561255a565b61260960408301846125cd565b949350505050565b5f805f6060848603121561262857612627611fa8565b5b5f612635868287016120dc565b93505060206126468682870161210f565b9250506040612657868287016120dc565b9150509250925092565b5f805f805f8060a0878903121561267b5761267a611fa8565b5b5f61268889828a016120dc565b965050602061269989828a016120dc565b95505060406126aa89828a0161210f565b94505060606126bb89828a0161210f565b935050608087013567ffffffffffffffff8111156126dc576126db611fac565b5b6126e889828a01612255565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f612761602a836126f7565b915061276c82612707565b604082019050919050565b5f6020820190508181035f83015261278e81612755565b9050919050565b5f819050919050565b6127af6127aa82612063565b612795565b82525050565b5f6127c0828461279e565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6127fb826127cf565b61280581856127d9565b93506128158185602086016127e3565b80840191505092915050565b5f61282c82846127f1565b915081905092915050565b5f815190506128458161206c565b92915050565b5f602082840312156128605761285f611fa8565b5b5f61286d84828501612837565b91505092915050565b5f8160601b9050919050565b5f61288c82612876565b9050919050565b5f61289d82612882565b9050919050565b6128b56128b0826120b5565b612893565b82525050565b5f819050919050565b6128d56128d0826120f0565b6128bb565b82525050565b5f6128e6828a6128a4565b6014820191506128f682896128a4565b601482019150612906828861279e565b602082019150612916828761279e565b60208201915061292682866128a4565b60148201915061293682856128c4565b60208201915061294682846128c4565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f61298f6013836126f7565b915061299a8261295b565b602082019050919050565b5f6020820190508181035f8301526129bc81612983565b9050919050565b6129cc81612063565b82525050565b5f6020820190506129e55f8301846129c3565b92915050565b6129f4816120b5565b82525050565b612a03816120f0565b82525050565b5f82825260208201905092915050565b50565b5f612a275f83612a09565b9150612a3282612a19565b5f82019050919050565b5f60a082019050612a4f5f8301876129eb565b612a5c60208301866129eb565b612a6960408301856129fa565b612a7660608301846129fa565b8181036080830152612a8781612a1c565b905095945050505050565b5f612a9d82896128a4565b601482019150612aad82886128a4565b601482019150612abd828761279e565b602082019150612acd828661279e565b602082019150612add82856128a4565b601482019150612aed82846128c4565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f612b5b6038836126f7565b9150612b6682612b01565b604082019050919050565b5f6020820190508181035f830152612b8881612b4f565b9050919050565b5f606082019050612ba25f8301866129eb565b612baf60208301856129eb565b612bbc60408301846129fa565b949350505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612c0e82612bc8565b810181811067ffffffffffffffff82111715612c2d57612c2c612bd8565b5b80604052505050565b5f612c3f611f9f565b9050612c4b8282612c05565b919050565b612c598161254b565b8114612c63575f80fd5b50565b5f81359050612c7481612c50565b92915050565b5f60c08284031215612c8f57612c8e612bc4565b5b612c9960c0612c36565b90505f612ca884828501612082565b5f830152506020612cbb848285016120dc565b6020830152506040612ccf848285016120dc565b6040830152506060612ce384828501612082565b6060830152506080612cf784828501612082565b60808301525060a0612d0b84828501612c66565b60a08301525092915050565b5f60c08284031215612d2c57612d2b611fa8565b5b5f612d3984828501612c7a565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f612d9c602a836126f7565b9150612da782612d42565b604082019050919050565b5f6020820190508181035f830152612dc981612d90565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612e04601e836126f7565b9150612e0f82612dd0565b602082019050919050565b5f6020820190508181035f830152612e3181612df8565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612e6c601e836126f7565b9150612e7782612e38565b602082019050919050565b5f6020820190508181035f830152612e9981612e60565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f612efa6023836126f7565b9150612f0582612ea0565b604082019050919050565b5f6020820190508181035f830152612f2781612eee565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f612f62601b836126f7565b9150612f6d82612f2e565b602082019050919050565b5f6020820190508181035f830152612f8f81612f56565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f612fca601a836126f7565b9150612fd582612f96565b602082019050919050565b5f6020820190508181035f830152612ff781612fbe565b9050919050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f613032601d836126f7565b915061303d82612ffe565b602082019050919050565b5f6020820190508181035f83015261305f81613026565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f61309a6015836126f7565b91506130a582613066565b602082019050919050565b5f6020820190508181035f8301526130c78161308e565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f613128602b836126f7565b9150613133826130ce565b604082019050919050565b5f6020820190508181035f8301526131558161311c565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f613190601c836126f7565b915061319b8261315c565b602082019050919050565b5f6020820190508181035f8301526131bd81613184565b905091905056fea2646970667358221220c7235610f4c08b95d1e01bd31ff0b8b671c0f18c33212760a2ce3b09e6ad77e964736f6c63430008190033"; pub trait CoinDockerOps { diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 5758aa3c02..23013be560 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -6,6 +6,7 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC7 SEPOLIA_NONCE_LOCK, SEPOLIA_RPC_URL, SEPOLIA_WEB3}; use crate::common::Future01CompatExt; use bitcrypto::{dhash160, sha256}; +use coins::eth::gas_limit::ETH_MAX_TRADE_GAS; use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_request, EthCoin, SignedEthTx, ERC20_ABI}; use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, ConfirmPaymentInput, DerivationMethod, @@ -48,11 +49,10 @@ pub fn swap_contract() -> Address { unsafe { GETH_SWAP_CONTRACT } } /// GETH_NFT_SWAP_CONTRACT is set once during initialization before tests start pub fn nft_swap_contract() -> Address { unsafe { GETH_NFT_SWAP_CONTRACT } } -#[allow(dead_code)] /// # Safety /// /// GETH_NFT_MAKER_SWAP_V2 is set once during initialization before tests start -pub fn nft_maker_swap_v2() -> Address { unsafe { GETH_NFT_MAKER_SWAP_V2 } } +pub fn geth_nft_maker_swap_v2() -> Address { unsafe { GETH_NFT_MAKER_SWAP_V2 } } /// # Safety /// @@ -67,17 +67,16 @@ pub fn erc20_contract() -> Address { unsafe { GETH_ERC20_CONTRACT } } /// Return ERC20 dev token contract address in checksum format pub fn erc20_contract_checksum() -> String { checksum_address(&format!("{:02x}", erc20_contract())) } -#[allow(dead_code)] /// # Safety /// /// GETH_ERC721_CONTRACT is set once during initialization before tests start -pub fn erc721_contract() -> Address { unsafe { GETH_ERC721_CONTRACT } } +pub fn geth_erc721_contract() -> Address { unsafe { GETH_ERC721_CONTRACT } } #[allow(dead_code)] /// # Safety /// /// GETH_ERC1155_CONTRACT is set once during initialization before tests start -pub fn erc1155_contract() -> Address { unsafe { GETH_ERC1155_CONTRACT } } +pub fn geth_erc1155_contract() -> Address { unsafe { GETH_ERC1155_CONTRACT } } /// # Safety /// @@ -143,13 +142,13 @@ fn fill_erc20(to_addr: Address, amount: U256) { wait_for_confirmation(tx_hash); } -#[allow(dead_code)] fn mint_erc721(to_addr: Address, token_id: U256) { let _guard = GETH_NONCE_LOCK.lock().unwrap(); - let erc721_contract = Contract::from_json(GETH_WEB3.eth(), erc721_contract(), ERC721_TEST_ABI.as_bytes()).unwrap(); + let erc721_contract = + Contract::from_json(GETH_WEB3.eth(), geth_erc721_contract(), ERC721_TEST_ABI.as_bytes()).unwrap(); let options = Options { - gas: Some(U256::from(150_000)), + gas: Some(U256::from(ETH_MAX_TRADE_GAS)), ..Options::default() }; @@ -179,9 +178,10 @@ fn erc712_owner(token_id: U256) -> Address { block_on(erc721_contract.query("ownerOf", Token::Uint(token_id), None, Options::default(), None)).unwrap() } -fn get_erc712_owner(token_id: U256) -> Address { +fn geth_erc712_owner(token_id: U256) -> Address { let _guard = GETH_NONCE_LOCK.lock().unwrap(); - let erc721_contract = Contract::from_json(GETH_WEB3.eth(), erc721_contract(), ERC721_TEST_ABI.as_bytes()).unwrap(); + let erc721_contract = + Contract::from_json(GETH_WEB3.eth(), geth_erc721_contract(), ERC721_TEST_ABI.as_bytes()).unwrap(); block_on(erc721_contract.query("ownerOf", Token::Uint(token_id), None, Options::default(), None)).unwrap() } @@ -189,7 +189,7 @@ fn get_erc712_owner(token_id: U256) -> Address { fn mint_erc1155(to_addr: Address, token_id: U256, amount: U256) { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc1155_contract = - Contract::from_json(GETH_WEB3.eth(), erc1155_contract(), ERC1155_TEST_ABI.as_bytes()).unwrap(); + Contract::from_json(GETH_WEB3.eth(), geth_erc1155_contract(), ERC1155_TEST_ABI.as_bytes()).unwrap(); let tx_hash = block_on(erc1155_contract.call( "mint", @@ -350,7 +350,6 @@ pub enum TestNftType { /// Generates a global NFT coin instance with a random private key and an initial 100 ETH balance. /// Optionally mints a specified NFT (either ERC721 or ERC1155) to the global NFT address, /// with details recorded in the `nfts_infos` field based on the provided `nft_type`. -#[allow(dead_code)] pub fn global_nft_with_random_privkey(swap_contract_address: Address, nft_type: Option) -> EthCoin { let nft_conf = nft_dev_conf(); let req = json!({ @@ -379,11 +378,16 @@ pub fn global_nft_with_random_privkey(swap_contract_address: Address, nft_type: match nft_type { TestNftType::Erc1155 { token_id, amount } => { mint_erc1155(my_address, U256::from(token_id), U256::from(amount)); - block_on(fill_erc1155_info(&global_nft, erc1155_contract(), token_id, amount)); + block_on(fill_erc1155_info( + &global_nft, + geth_erc1155_contract(), + token_id, + amount, + )); }, TestNftType::Erc721 { token_id } => { mint_erc721(my_address, U256::from(token_id)); - block_on(fill_erc721_info(&global_nft, erc721_contract(), token_id)); + block_on(fill_erc721_info(&global_nft, geth_erc721_contract(), token_id)); }, } } @@ -480,7 +484,12 @@ fn send_safe_transfer_from( let result = block_on( global_nft - .sign_and_send_transaction(0.into(), Action::Call(token_address), data, U256::from(150_000)) + .sign_and_send_transaction( + 0.into(), + Action::Call(token_address), + data, + U256::from(ETH_MAX_TRADE_GAS), + ) .compat(), ) .unwrap(); @@ -1185,16 +1194,12 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { let token_id = 3u32; let erc721_nft = TestNftType::Erc721 { token_id }; - let maker_global_nft = global_nft_with_random_privkey(nft_maker_swap_v2(), Some(erc721_nft)); - let taker_global_nft = global_nft_with_random_privkey(nft_maker_swap_v2(), None); + let maker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), Some(erc721_nft)); + let taker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), None); let maker_address = block_on(maker_global_nft.my_addr()); - log!("maker_address: {:?}", maker_address); - let taker_address = block_on(taker_global_nft.my_addr()); - log!("taker_address: {:?}", taker_address); let time_lock_to_refund = now_sec() - 1000; - log!("time_lock_to_refund: {}", time_lock_to_refund); let taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); let maker_secret = &[1; 32]; @@ -1203,10 +1208,10 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { let taker_secret_hash = sha256(taker_secret).to_vec(); let nft_swap_info = NftSwapInfo { - token_address: &erc721_contract(), + token_address: &geth_erc721_contract(), token_id: &BigUint::from(token_id).to_bytes(), contract_type: &ContractType::Erc721, - swap_contract_address: &nft_maker_swap_v2(), + swap_contract_address: &geth_nft_maker_swap_v2(), }; let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { @@ -1233,18 +1238,8 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { }; maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - let payment_hash_refund = calculate_payment_hash( - &taker_address, - &maker_address, - &taker_secret_hash, - &maker_secret_hash, - &erc721_contract(), - token_id, - ); - println!("payment_hash_refund: {:?}", payment_hash_refund); - - let current_owner = get_erc712_owner(U256::from(token_id)); - assert_eq!(current_owner, nft_maker_swap_v2()); + let current_owner = geth_erc712_owner(U256::from(token_id)); + assert_eq!(current_owner, geth_nft_maker_swap_v2()); let refund_timelock_args = RefundNftMakerPaymentArgs { maker_payment_tx: &maker_payment_to_refund, @@ -1253,7 +1248,7 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { taker_secret, swap_unique_data: &[], contract_type: &ContractType::Erc721, - swap_contract_address: &nft_maker_swap_v2(), + swap_contract_address: &geth_nft_maker_swap_v2(), }; let refund_timelock_tx = block_on(maker_global_nft.refund_nft_maker_payment_v2_timelock(refund_timelock_args)).unwrap(); @@ -1270,37 +1265,6 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { }; maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - let current_owner = get_erc712_owner(U256::from(token_id)); + let current_owner = geth_erc712_owner(U256::from(token_id)); assert_eq!(current_owner, maker_address); } - -// test function -fn calculate_payment_hash( - taker: &Address, - sender: &Address, - taker_secret_hash: &[u8], - maker_secret_hash: &[u8], - token_address: &Address, - token_id: u32, -) -> [u8; 20] { - use bitcrypto::ripemd160; - // Convert token_id to a 256-bit representation as Solidity does with abi.encodePacked - let token_id_bytes = { - let mut buf = [0u8; 32]; - buf[28..32].copy_from_slice(&token_id.to_be_bytes()); - buf - }; - - // Encode the data as Solidity would do with abi.encodePacked - let mut encoded = Vec::new(); - encoded.extend_from_slice(taker.as_bytes()); - encoded.extend_from_slice(sender.as_bytes()); - encoded.extend_from_slice(taker_secret_hash); - encoded.extend_from_slice(maker_secret_hash); - encoded.extend_from_slice(token_address.as_bytes()); - encoded.extend_from_slice(&token_id_bytes); - - // Hash with RIPEMD160 - let payment_hash = ripemd160(&encoded); - *payment_hash -} From fc4d6e49a5c7853f1de319481f00f81e6abb147d Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 28 May 2024 18:55:37 +0700 Subject: [PATCH 046/233] impl [test] send_send_and_refund_erc1155_maker_payment_timelock --- .../tests/docker_tests/eth_docker_tests.rs | 97 ++++++++++++++++++- 1 file changed, 95 insertions(+), 2 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 23013be560..64b879bf2a 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -72,7 +72,6 @@ pub fn erc20_contract_checksum() -> String { checksum_address(&format!("{:02x}", /// GETH_ERC721_CONTRACT is set once during initialization before tests start pub fn geth_erc721_contract() -> Address { unsafe { GETH_ERC721_CONTRACT } } -#[allow(dead_code)] /// # Safety /// /// GETH_ERC1155_CONTRACT is set once during initialization before tests start @@ -185,7 +184,6 @@ fn geth_erc712_owner(token_id: U256) -> Address { block_on(erc721_contract.query("ownerOf", Token::Uint(token_id), None, Options::default(), None)).unwrap() } -#[allow(dead_code)] fn mint_erc1155(to_addr: Address, token_id: U256, amount: U256) { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc1155_contract = @@ -236,6 +234,20 @@ fn erc1155_balance(wallet_addr: Address, token_id: U256) -> U256 { .unwrap() } +fn geth_erc1155_balance(wallet_addr: Address, token_id: U256) -> U256 { + let _guard = GETH_NONCE_LOCK.lock().unwrap(); + let erc1155_contract = + Contract::from_json(GETH_WEB3.eth(), geth_erc1155_contract(), ERC1155_TEST_ABI.as_bytes()).unwrap(); + block_on(erc1155_contract.query( + "balanceOf", + (Token::Address(wallet_addr), Token::Uint(token_id)), + None, + Options::default(), + None, + )) + .unwrap() +} + pub(crate) async fn fill_erc1155_info(eth_coin: &EthCoin, token_address: Address, token_id: u32, amount: u32) { let nft_infos_lock = eth_coin.nfts_infos.clone(); let mut nft_infos = nft_infos_lock.lock().await; @@ -1268,3 +1280,84 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { let current_owner = geth_erc712_owner(U256::from(token_id)); assert_eq!(current_owner, maker_address); } + +#[test] +fn send_send_and_refund_erc1155_maker_payment_timelock() { + let token_id = 3u32; + let amount = 3u32; + let erc1155_nft = TestNftType::Erc1155 { token_id, amount }; + + let maker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), Some(erc1155_nft)); + let taker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), None); + + let maker_address = block_on(maker_global_nft.my_addr()); + + let time_lock_to_refund = now_sec() - 1000; + let taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); + + let maker_secret = &[1; 32]; + let maker_secret_hash = sha256(maker_secret).to_vec(); + let taker_secret = &[0; 32]; + let taker_secret_hash = sha256(taker_secret).to_vec(); + + let nft_swap_info = NftSwapInfo { + token_address: &geth_erc1155_contract(), + token_id: &BigUint::from(token_id).to_bytes(), + contract_type: &ContractType::Erc1155, + swap_contract_address: &geth_nft_maker_swap_v2(), + }; + + let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { + time_lock: time_lock_to_refund, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + amount: amount.into(), + taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), + swap_unique_data: &[], + nft_swap_info: &nft_swap_info, + }; + let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); + log!( + "Maker sent ERC1155 NFT payment, tx hash: {:02x}", + maker_payment_to_refund.tx_hash() + ); + + let confirm_input = ConfirmPaymentInput { + payment_tx: maker_payment_to_refund.tx_hex(), + confirmations: 1, + requires_nota: false, + wait_until: now_sec() + 70, + check_every: 1, + }; + maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + + let balance = geth_erc1155_balance(geth_nft_maker_swap_v2(), U256::from(token_id)); + assert_eq!(U256::from(amount), balance); + + let refund_timelock_args = RefundNftMakerPaymentArgs { + maker_payment_tx: &maker_payment_to_refund, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + taker_secret, + swap_unique_data: &[], + contract_type: &ContractType::Erc1155, + swap_contract_address: &geth_nft_maker_swap_v2(), + }; + let refund_timelock_tx = + block_on(maker_global_nft.refund_nft_maker_payment_v2_timelock(refund_timelock_args)).unwrap(); + log!( + "Maker refunded ERC1155 NFT Maker payment Timelock, tx hash: {:02x}", + refund_timelock_tx.tx_hash() + ); + let confirm_input = ConfirmPaymentInput { + payment_tx: refund_timelock_tx.tx_hex(), + confirmations: 1, + requires_nota: false, + wait_until: now_sec() + 70, + check_every: 1, + }; + maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + + let balance = geth_erc1155_balance(maker_address, U256::from(token_id)); + assert_eq!(U256::from(amount), balance); +} From cc8e78ebe0efb112581ab16dbd43d7e98e6665de Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 29 May 2024 14:38:27 +0700 Subject: [PATCH 047/233] test the refund payment with taker secret --- .../tests/docker_tests/eth_docker_tests.rs | 171 +++++++++++++++++- 1 file changed, 165 insertions(+), 6 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 64b879bf2a..5ba111bd76 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1202,7 +1202,7 @@ fn test_nonce_lock() { } #[test] -fn send_send_and_refund_erc721_maker_payment_timelock() { +fn send_and_refund_erc721_maker_payment_timelock() { let token_id = 3u32; let erc721_nft = TestNftType::Erc721 { token_id }; @@ -1245,7 +1245,7 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { payment_tx: maker_payment_to_refund.tx_hex(), confirmations: 1, requires_nota: false, - wait_until: now_sec() + 200, + wait_until: now_sec() + 100, check_every: 1, }; maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); @@ -1265,14 +1265,14 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { let refund_timelock_tx = block_on(maker_global_nft.refund_nft_maker_payment_v2_timelock(refund_timelock_args)).unwrap(); log!( - "Maker refunded ERC721 NFT Maker payment Timelock, tx hash: {:02x}", + "Maker refunded ERC721 NFT payment after timelock, tx hash: {:02x}", refund_timelock_tx.tx_hash() ); let confirm_input = ConfirmPaymentInput { payment_tx: refund_timelock_tx.tx_hex(), confirmations: 1, requires_nota: false, - wait_until: now_sec() + 200, + wait_until: now_sec() + 100, check_every: 1, }; maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); @@ -1282,7 +1282,7 @@ fn send_send_and_refund_erc721_maker_payment_timelock() { } #[test] -fn send_send_and_refund_erc1155_maker_payment_timelock() { +fn send_and_refund_erc1155_maker_payment_timelock() { let token_id = 3u32; let amount = 3u32; let erc1155_nft = TestNftType::Erc1155 { token_id, amount }; @@ -1346,7 +1346,7 @@ fn send_send_and_refund_erc1155_maker_payment_timelock() { let refund_timelock_tx = block_on(maker_global_nft.refund_nft_maker_payment_v2_timelock(refund_timelock_args)).unwrap(); log!( - "Maker refunded ERC1155 NFT Maker payment Timelock, tx hash: {:02x}", + "Maker refunded ERC1155 NFT payment after timelock, tx hash: {:02x}", refund_timelock_tx.tx_hash() ); let confirm_input = ConfirmPaymentInput { @@ -1361,3 +1361,162 @@ fn send_send_and_refund_erc1155_maker_payment_timelock() { let balance = geth_erc1155_balance(maker_address, U256::from(token_id)); assert_eq!(U256::from(amount), balance); } + +#[test] +fn send_and_refund_erc721_maker_payment_secret() { + let token_id = 4u32; + let erc721_nft = TestNftType::Erc721 { token_id }; + + let maker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), Some(erc721_nft)); + let taker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), None); + + let maker_address = block_on(maker_global_nft.my_addr()); + + let time_lock_to_refund = now_sec() + 1000; + let taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); + + let maker_secret = &[1; 32]; + let maker_secret_hash = sha256(maker_secret).to_vec(); + let taker_secret = &[0; 32]; + let taker_secret_hash = sha256(taker_secret).to_vec(); + + let nft_swap_info = NftSwapInfo { + token_address: &geth_erc721_contract(), + token_id: &BigUint::from(token_id).to_bytes(), + contract_type: &ContractType::Erc721, + swap_contract_address: &geth_nft_maker_swap_v2(), + }; + + let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { + time_lock: time_lock_to_refund, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + amount: 1.into(), + taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), + swap_unique_data: &[], + nft_swap_info: &nft_swap_info, + }; + let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); + log!( + "Maker sent ERC721 NFT payment, tx hash: {:02x}", + maker_payment_to_refund.tx_hash() + ); + + let confirm_input = ConfirmPaymentInput { + payment_tx: maker_payment_to_refund.tx_hex(), + confirmations: 1, + requires_nota: false, + wait_until: now_sec() + 100, + check_every: 1, + }; + maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + + let current_owner = geth_erc712_owner(U256::from(token_id)); + assert_eq!(current_owner, geth_nft_maker_swap_v2()); + + let refund_secret_args = RefundNftMakerPaymentArgs { + maker_payment_tx: &maker_payment_to_refund, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + taker_secret, + swap_unique_data: &[], + contract_type: &ContractType::Erc721, + swap_contract_address: &geth_nft_maker_swap_v2(), + }; + let refund_secret_tx = block_on(maker_global_nft.refund_nft_maker_payment_v2_secret(refund_secret_args)).unwrap(); + log!( + "Maker refunded ERC721 NFT payment using Taker secret, tx hash: {:02x}", + refund_secret_tx.tx_hash() + ); + let confirm_input = ConfirmPaymentInput { + payment_tx: refund_secret_tx.tx_hex(), + confirmations: 1, + requires_nota: false, + wait_until: now_sec() + 100, + check_every: 1, + }; + maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + + let current_owner = geth_erc712_owner(U256::from(token_id)); + assert_eq!(current_owner, maker_address); +} + +#[test] +fn send_and_refund_erc1155_maker_payment_secret() { + let token_id = 4u32; + let amount = 3u32; + let erc1155_nft = TestNftType::Erc1155 { token_id, amount }; + + let maker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), Some(erc1155_nft)); + let taker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), None); + + let maker_address = block_on(maker_global_nft.my_addr()); + + let time_lock_to_refund = now_sec() - 1000; + let taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); + + let maker_secret = &[1; 32]; + let maker_secret_hash = sha256(maker_secret).to_vec(); + let taker_secret = &[0; 32]; + let taker_secret_hash = sha256(taker_secret).to_vec(); + + let nft_swap_info = NftSwapInfo { + token_address: &geth_erc1155_contract(), + token_id: &BigUint::from(token_id).to_bytes(), + contract_type: &ContractType::Erc1155, + swap_contract_address: &geth_nft_maker_swap_v2(), + }; + + let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { + time_lock: time_lock_to_refund, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + amount: amount.into(), + taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), + swap_unique_data: &[], + nft_swap_info: &nft_swap_info, + }; + let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); + log!( + "Maker sent ERC1155 NFT payment, tx hash: {:02x}", + maker_payment_to_refund.tx_hash() + ); + + let confirm_input = ConfirmPaymentInput { + payment_tx: maker_payment_to_refund.tx_hex(), + confirmations: 1, + requires_nota: false, + wait_until: now_sec() + 70, + check_every: 1, + }; + maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + + let balance = geth_erc1155_balance(geth_nft_maker_swap_v2(), U256::from(token_id)); + assert_eq!(U256::from(amount), balance); + + let refund_secret_args = RefundNftMakerPaymentArgs { + maker_payment_tx: &maker_payment_to_refund, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + taker_secret, + swap_unique_data: &[], + contract_type: &ContractType::Erc1155, + swap_contract_address: &geth_nft_maker_swap_v2(), + }; + let refund_secret_tx = block_on(maker_global_nft.refund_nft_maker_payment_v2_secret(refund_secret_args)).unwrap(); + log!( + "Maker refunded ERC1155 NFT payment using Taker secret, tx hash: {:02x}", + refund_secret_tx.tx_hash() + ); + let confirm_input = ConfirmPaymentInput { + payment_tx: refund_secret_tx.tx_hex(), + confirmations: 1, + requires_nota: false, + wait_until: now_sec() + 70, + check_every: 1, + }; + maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + + let balance = geth_erc1155_balance(maker_address, U256::from(token_id)); + assert_eq!(U256::from(amount), balance); +} From 87b297a8110e82edabf4831faf23cebb13d2ca16 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 29 May 2024 18:07:22 +0700 Subject: [PATCH 048/233] use Geth node for swap tests --- .../tests/docker_tests/eth_docker_tests.rs | 167 +++++------------- 1 file changed, 49 insertions(+), 118 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 5ba111bd76..0a3d9562c3 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1,7 +1,7 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC721_TEST_ABI, GETH_ACCOUNT, GETH_ERC1155_CONTRACT, GETH_ERC20_CONTRACT, GETH_ERC721_CONTRACT, GETH_NFT_MAKER_SWAP_V2, GETH_NFT_SWAP_CONTRACT, GETH_NONCE_LOCK, GETH_RPC_URL, - GETH_SWAP_CONTRACT, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, MM_CTX, MM_CTX1, + GETH_SWAP_CONTRACT, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, MM_CTX, SEPOLIA_ERC1155_CONTRACT, SEPOLIA_ERC721_CONTRACT, SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2, SEPOLIA_NONCE_LOCK, SEPOLIA_RPC_URL, SEPOLIA_WEB3}; use crate::common::Future01CompatExt; @@ -29,7 +29,9 @@ use web3::contract::{Contract, Options}; use web3::ethabi::Token; use web3::types::{Address, BlockNumber, TransactionRequest, H256}; +#[allow(dead_code)] const SEPOLIA_MAKER_PRIV: &str = "6e2f3a6223b928a05a3a3622b0c3f3573d03663b704a61a6eb73326de0487928"; +#[allow(dead_code)] const SEPOLIA_TAKER_PRIV: &str = "e0be82dca60ff7e4c6d6db339ac9e1ae249af081dba2110bddd281e711608f16"; const NFT_ETH: &str = "NFT_ETH"; @@ -77,16 +79,19 @@ pub fn geth_erc721_contract() -> Address { unsafe { GETH_ERC721_CONTRACT } } /// GETH_ERC1155_CONTRACT is set once during initialization before tests start pub fn geth_erc1155_contract() -> Address { unsafe { GETH_ERC1155_CONTRACT } } +#[allow(dead_code)] /// # Safety /// /// SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2 address is set once during initialization before tests start pub fn sepolia_etomic_maker_nft() -> Address { unsafe { SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2 } } +#[allow(dead_code)] /// # Safety /// /// SEPOLIA_ERC721_CONTRACT address is set once during initialization before tests start pub fn sepolia_erc721() -> Address { unsafe { SEPOLIA_ERC721_CONTRACT } } +#[allow(dead_code)] /// # Safety /// /// SEPOLIA_ERC1155_CONTRACT address is set once during initialization before tests start @@ -170,13 +175,6 @@ fn mint_erc721(to_addr: Address, token_id: U256) { ); } -fn erc712_owner(token_id: U256) -> Address { - let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); - let erc721_contract = - Contract::from_json(SEPOLIA_WEB3.eth(), sepolia_erc721(), ERC721_TEST_ABI.as_bytes()).unwrap(); - block_on(erc721_contract.query("ownerOf", Token::Uint(token_id), None, Options::default(), None)).unwrap() -} - fn geth_erc712_owner(token_id: U256) -> Address { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc721_contract = @@ -220,20 +218,6 @@ fn mint_erc1155(to_addr: Address, token_id: U256, amount: U256) { ); } -fn erc1155_balance(wallet_addr: Address, token_id: U256) -> U256 { - let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); - let erc1155_contract = - Contract::from_json(SEPOLIA_WEB3.eth(), sepolia_erc1155(), ERC1155_TEST_ABI.as_bytes()).unwrap(); - block_on(erc1155_contract.query( - "balanceOf", - (Token::Address(wallet_addr), Token::Uint(token_id)), - None, - Options::default(), - None, - )) - .unwrap() -} - fn geth_erc1155_balance(wallet_addr: Address, token_id: U256) -> U256 { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc1155_contract = @@ -407,6 +391,8 @@ pub fn global_nft_with_random_privkey(swap_contract_address: Address, nft_type: global_nft } +#[allow(dead_code)] +/// Can be used to generate global NFT from Sepolia Maker/Taker priv keys. fn global_nft_from_privkey( ctx: &MmArc, swap_contract_address: Address, @@ -455,6 +441,7 @@ fn global_nft_from_privkey( global_nft } +#[allow(dead_code)] fn send_safe_transfer_from( global_nft: &EthCoin, token_address: Address, @@ -462,7 +449,7 @@ fn send_safe_transfer_from( to_address: Address, nft_type: TestNftType, ) -> web3::Result { - let _guard = GETH_NONCE_LOCK.lock().unwrap(); + let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); let contract = match nft_type { TestNftType::Erc1155 { .. } => { @@ -897,6 +884,7 @@ fn send_and_spend_erc20_maker_payment_priority_fee() { send_and_spend_erc20_maker_payment_impl(SwapTxFeePolicy::Medium); } +#[allow(dead_code)] /// Wait for all pending transactions for the given address to be confirmed fn wait_pending_transactions(wallet_address: Address) { let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); @@ -919,6 +907,7 @@ fn wait_pending_transactions(wallet_address: Address) { } } +#[allow(dead_code)] fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option) -> EthCoin { match block_on(lp_coinfind(ctx, NFT_ETH)).unwrap() { None => global_nft_from_privkey(ctx, sepolia_etomic_maker_nft(), priv_key, nft_type), @@ -930,35 +919,34 @@ fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option = SendNftMakerPaymentArgs { time_lock, - taker_secret_hash: &[0; 32], + taker_secret_hash: &taker_secret_hash, maker_secret_hash: &maker_secret_hash, amount: 1.into(), taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), @@ -975,7 +963,7 @@ fn send_and_spend_erc721_maker_payment() { payment_tx: maker_payment.tx_hex(), confirmations: 1, requires_nota: false, - wait_until: now_sec() + 150, + wait_until: now_sec() + 100, check_every: 1, }; maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); @@ -983,7 +971,7 @@ fn send_and_spend_erc721_maker_payment() { let validate_args = ValidateNftMakerPaymentArgs { maker_payment_tx: &maker_payment, time_lock, - taker_secret_hash: &[0; 32], + taker_secret_hash: &taker_secret_hash, maker_secret_hash: &maker_secret_hash, amount: 1.into(), taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), @@ -993,17 +981,15 @@ fn send_and_spend_erc721_maker_payment() { }; block_on(maker_global_nft.validate_nft_maker_payment_v2(validate_args)).unwrap(); - wait_pending_transactions(maker_address); - let spend_payment_args = SpendNftMakerPaymentArgs { maker_payment_tx: &maker_payment, - taker_secret_hash: &[0; 32], + taker_secret_hash: &taker_secret_hash, maker_secret_hash: &maker_secret_hash, maker_secret, maker_pub: &maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), swap_unique_data: &[], contract_type: &ContractType::Erc721, - swap_contract_address: &sepolia_etomic_maker_nft(), + swap_contract_address: &geth_nft_maker_swap_v2(), }; let spend_tx = block_on(taker_global_nft.spend_nft_maker_payment_v2(spend_payment_args)).unwrap(); log!( @@ -1015,53 +1001,25 @@ fn send_and_spend_erc721_maker_payment() { payment_tx: spend_tx.tx_hex(), confirmations: 1, requires_nota: false, - wait_until: now_sec() + 150, + wait_until: now_sec() + 100, check_every: 1, }; taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - let new_owner = erc712_owner(U256::from(1)); - let taker_address = block_on(taker_global_nft.my_addr()); + let new_owner = geth_erc712_owner(U256::from(token_id)); assert_eq!(new_owner, taker_address); - - // send nft back to maker - let send_back_tx = send_safe_transfer_from( - &taker_global_nft, - sepolia_erc721(), - taker_address, - maker_address, - erc721_nft, - ) - .unwrap(); - log!( - "Taker sent ERC721 NFT back to Maker, tx hash: {:02x}", - send_back_tx.tx_hash() - ); - let confirm_input = ConfirmPaymentInput { - payment_tx: send_back_tx.tx_hex(), - confirmations: 1, - requires_nota: false, - wait_until: now_sec() + 150, - check_every: 1, - }; - taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - - let new_owner = erc712_owner(U256::from(1)); - assert_eq!(new_owner, maker_address); } #[test] -#[ignore] fn send_and_spend_erc1155_maker_payment() { - // Sepolia Maker owns tokenId = 1, amount = 3 - - let erc1155_nft = TestNftType::Erc1155 { token_id: 1, amount: 3 }; + let token_id = 1u32; + let amount = 3u32; + let erc1155_nft = TestNftType::Erc1155 { token_id, amount }; - let maker_global_nft = get_or_create_nft(&MM_CTX, SEPOLIA_MAKER_PRIV, Some(erc1155_nft)); - let taker_global_nft = get_or_create_nft(&MM_CTX1, SEPOLIA_TAKER_PRIV, None); + let maker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), Some(erc1155_nft)); + let taker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), None); - let maker_address = block_on(maker_global_nft.my_addr()); - wait_pending_transactions(maker_address); + let taker_address = block_on(taker_global_nft.my_addr()); let time_lock = now_sec() + 1000; let maker_pubkey = maker_global_nft.derive_htlc_pubkey(&[]); @@ -1069,19 +1027,21 @@ fn send_and_spend_erc1155_maker_payment() { let maker_secret = &[1; 32]; let maker_secret_hash = sha256(maker_secret).to_vec(); + let taker_secret = &[0; 32]; + let taker_secret_hash = sha256(taker_secret).to_vec(); let nft_swap_info = NftSwapInfo { - token_address: &sepolia_erc1155(), - token_id: &BigUint::from(1u32).to_bytes(), + token_address: &geth_erc1155_contract(), + token_id: &BigUint::from(token_id).to_bytes(), contract_type: &ContractType::Erc1155, - swap_contract_address: &sepolia_etomic_maker_nft(), + swap_contract_address: &geth_nft_maker_swap_v2(), }; let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { time_lock, - taker_secret_hash: &[0; 32], + taker_secret_hash: &taker_secret_hash, maker_secret_hash: &maker_secret_hash, - amount: 3.into(), + amount: amount.into(), taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), swap_unique_data: &[], nft_swap_info: &nft_swap_info, @@ -1104,9 +1064,9 @@ fn send_and_spend_erc1155_maker_payment() { let validate_args = ValidateNftMakerPaymentArgs { maker_payment_tx: &maker_payment, time_lock, - taker_secret_hash: &[0; 32], + taker_secret_hash: &taker_secret_hash, maker_secret_hash: &maker_secret_hash, - amount: 3.into(), + amount: amount.into(), taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), maker_pub: &maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), swap_unique_data: &[], @@ -1114,17 +1074,15 @@ fn send_and_spend_erc1155_maker_payment() { }; block_on(maker_global_nft.validate_nft_maker_payment_v2(validate_args)).unwrap(); - wait_pending_transactions(maker_address); - let spend_payment_args = SpendNftMakerPaymentArgs { maker_payment_tx: &maker_payment, - taker_secret_hash: &[0; 32], + taker_secret_hash: &taker_secret_hash, maker_secret_hash: &maker_secret_hash, maker_secret, maker_pub: &maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), swap_unique_data: &[], contract_type: &ContractType::Erc1155, - swap_contract_address: &sepolia_etomic_maker_nft(), + swap_contract_address: &geth_nft_maker_swap_v2(), }; let spend_tx = block_on(taker_global_nft.spend_nft_maker_payment_v2(spend_payment_args)).unwrap(); log!( @@ -1141,35 +1099,8 @@ fn send_and_spend_erc1155_maker_payment() { }; taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - let taker_address = block_on(taker_global_nft.my_addr()); - let balance = erc1155_balance(taker_address, U256::from(1)); - assert_eq!(balance, U256::from(3)); - - // send nft back to maker - let maker_address = block_on(maker_global_nft.my_addr()); - let send_back_tx = send_safe_transfer_from( - &taker_global_nft, - sepolia_erc1155(), - taker_address, - maker_address, - erc1155_nft, - ) - .unwrap(); - log!( - "Taker sent ERC1155 NFT back to Maker, tx hash: {:02x}", - send_back_tx.tx_hash() - ); - let confirm_input = ConfirmPaymentInput { - payment_tx: send_back_tx.tx_hex(), - confirmations: 1, - requires_nota: false, - wait_until: now_sec() + 80, - check_every: 1, - }; - taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - - let balance = erc1155_balance(maker_address, U256::from(1)); - assert_eq!(balance, U256::from(3)); + let balance = geth_erc1155_balance(taker_address, U256::from(token_id)); + assert_eq!(U256::from(amount), balance); } #[test] From 780b1e80abe8ee73363e297048f2eff37a6f421a Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 30 May 2024 18:37:18 +0700 Subject: [PATCH 049/233] reduce code duplication --- .../tests/docker_tests/eth_docker_tests.rs | 638 ++++++++---------- 1 file changed, 265 insertions(+), 373 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 0a3d9562c3..19ef7f2405 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -11,7 +11,7 @@ use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_reque use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, ConfirmPaymentInput, DerivationMethod, Eip1559Ops, FoundSwapTxSpend, MakerNftSwapOpsV2, MarketCoinOps, MmCoinEnum, MmCoinStruct, NftSwapInfo, - ParseCoinAssocTypes, PrivKeyBuildPolicy, RefundNftMakerPaymentArgs, RefundPaymentArgs, + ParseCoinAssocTypes, ParseNftAssocTypes, PrivKeyBuildPolicy, RefundNftMakerPaymentArgs, RefundPaymentArgs, SearchForSwapTxSpendInput, SendNftMakerPaymentArgs, SendPaymentArgs, SpendNftMakerPaymentArgs, SpendPaymentArgs, SwapOps, SwapTxFeePolicy, SwapTxTypeWithSecretHash, ToBytes, Transaction, ValidateNftMakerPaymentArgs}; @@ -921,92 +921,34 @@ fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option = SendNftMakerPaymentArgs { + let setup = setup_test( + token_id, + None, + ContractType::Erc721, + geth_nft_maker_swap_v2(), + geth_erc721_contract(), time_lock, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - amount: 1.into(), - taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), - swap_unique_data: &[], - nft_swap_info: &nft_swap_info, - }; - let maker_payment = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); + ); + + let maker_payment = send_nft_maker_payment(&setup, 1.into()); log!( "Maker sent ERC721 NFT payment, tx hash: {:02x}", maker_payment.tx_hash() ); - let confirm_input = ConfirmPaymentInput { - payment_tx: maker_payment.tx_hex(), - confirmations: 1, - requires_nota: false, - wait_until: now_sec() + 100, - check_every: 1, - }; - maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - - let validate_args = ValidateNftMakerPaymentArgs { - maker_payment_tx: &maker_payment, - time_lock, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - amount: 1.into(), - taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), - maker_pub: &maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), - swap_unique_data: &[], - nft_swap_info: &nft_swap_info, - }; - block_on(maker_global_nft.validate_nft_maker_payment_v2(validate_args)).unwrap(); + wait_for_confirmations(&setup.maker_global_nft, &maker_payment, 90); + validate_nft_maker_payment(&setup, &maker_payment, 1.into()); - let spend_payment_args = SpendNftMakerPaymentArgs { - maker_payment_tx: &maker_payment, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - maker_secret, - maker_pub: &maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), - swap_unique_data: &[], - contract_type: &ContractType::Erc721, - swap_contract_address: &geth_nft_maker_swap_v2(), - }; - let spend_tx = block_on(taker_global_nft.spend_nft_maker_payment_v2(spend_payment_args)).unwrap(); + let spend_tx = spend_nft_maker_payment(&setup, &maker_payment, &ContractType::Erc721); log!( "Taker spent ERC721 NFT Maker payment, tx hash: {:02x}", spend_tx.tx_hash() ); - let confirm_input = ConfirmPaymentInput { - payment_tx: spend_tx.tx_hex(), - confirmations: 1, - requires_nota: false, - wait_until: now_sec() + 100, - check_every: 1, - }; - taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - + wait_for_confirmations(&setup.taker_global_nft, &spend_tx, 90); let new_owner = geth_erc712_owner(U256::from(token_id)); + let taker_address = block_on(setup.taker_global_nft.my_addr()); assert_eq!(new_owner, taker_address); } @@ -1014,91 +956,33 @@ fn send_and_spend_erc721_maker_payment() { fn send_and_spend_erc1155_maker_payment() { let token_id = 1u32; let amount = 3u32; - let erc1155_nft = TestNftType::Erc1155 { token_id, amount }; - - let maker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), Some(erc1155_nft)); - let taker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), None); - - let taker_address = block_on(taker_global_nft.my_addr()); - let time_lock = now_sec() + 1000; - let maker_pubkey = maker_global_nft.derive_htlc_pubkey(&[]); - let taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); - - let maker_secret = &[1; 32]; - let maker_secret_hash = sha256(maker_secret).to_vec(); - let taker_secret = &[0; 32]; - let taker_secret_hash = sha256(taker_secret).to_vec(); - - let nft_swap_info = NftSwapInfo { - token_address: &geth_erc1155_contract(), - token_id: &BigUint::from(token_id).to_bytes(), - contract_type: &ContractType::Erc1155, - swap_contract_address: &geth_nft_maker_swap_v2(), - }; - - let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { + let setup = setup_test( + token_id, + Some(amount), + ContractType::Erc1155, + geth_nft_maker_swap_v2(), + geth_erc1155_contract(), time_lock, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - amount: amount.into(), - taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), - swap_unique_data: &[], - nft_swap_info: &nft_swap_info, - }; - let maker_payment = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); + ); + + let maker_payment = send_nft_maker_payment(&setup, amount.into()); log!( "Maker sent ERC1155 NFT payment, tx hash: {:02x}", maker_payment.tx_hash() ); - let confirm_input = ConfirmPaymentInput { - payment_tx: maker_payment.tx_hex(), - confirmations: 1, - requires_nota: false, - wait_until: now_sec() + 80, - check_every: 1, - }; - maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + wait_for_confirmations(&setup.maker_global_nft, &maker_payment, 80); + validate_nft_maker_payment(&setup, &maker_payment, amount.into()); - let validate_args = ValidateNftMakerPaymentArgs { - maker_payment_tx: &maker_payment, - time_lock, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - amount: amount.into(), - taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), - maker_pub: &maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), - swap_unique_data: &[], - nft_swap_info: &nft_swap_info, - }; - block_on(maker_global_nft.validate_nft_maker_payment_v2(validate_args)).unwrap(); - - let spend_payment_args = SpendNftMakerPaymentArgs { - maker_payment_tx: &maker_payment, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - maker_secret, - maker_pub: &maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), - swap_unique_data: &[], - contract_type: &ContractType::Erc1155, - swap_contract_address: &geth_nft_maker_swap_v2(), - }; - let spend_tx = block_on(taker_global_nft.spend_nft_maker_payment_v2(spend_payment_args)).unwrap(); + let spend_tx = spend_nft_maker_payment(&setup, &maker_payment, &ContractType::Erc1155); log!( "Taker spent ERC1155 NFT Maker payment, tx hash: {:02x}", spend_tx.tx_hash() ); - let confirm_input = ConfirmPaymentInput { - payment_tx: spend_tx.tx_hex(), - confirmations: 1, - requires_nota: false, - wait_until: now_sec() + 80, - check_every: 1, - }; - taker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - + wait_for_confirmations(&setup.taker_global_nft, &spend_tx, 80); + let taker_address = block_on(setup.taker_global_nft.my_addr()); let balance = geth_erc1155_balance(taker_address, U256::from(token_id)); assert_eq!(U256::from(amount), balance); } @@ -1134,320 +1018,328 @@ fn test_nonce_lock() { #[test] fn send_and_refund_erc721_maker_payment_timelock() { - let token_id = 3u32; - let erc721_nft = TestNftType::Erc721 { token_id }; - - let maker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), Some(erc721_nft)); - let taker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), None); - - let maker_address = block_on(maker_global_nft.my_addr()); - + let token_id = 2u32; let time_lock_to_refund = now_sec() - 1000; - let taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); - - let maker_secret = &[1; 32]; - let maker_secret_hash = sha256(maker_secret).to_vec(); - let taker_secret = &[0; 32]; - let taker_secret_hash = sha256(taker_secret).to_vec(); - - let nft_swap_info = NftSwapInfo { - token_address: &geth_erc721_contract(), - token_id: &BigUint::from(token_id).to_bytes(), - contract_type: &ContractType::Erc721, - swap_contract_address: &geth_nft_maker_swap_v2(), - }; + let setup = setup_test( + token_id, + None, + ContractType::Erc721, + geth_nft_maker_swap_v2(), + geth_erc721_contract(), + time_lock_to_refund, + ); - let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { - time_lock: time_lock_to_refund, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - amount: 1.into(), - taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), - swap_unique_data: &[], - nft_swap_info: &nft_swap_info, - }; - let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); + let maker_payment_to_refund = send_nft_maker_payment(&setup, 1.into()); log!( "Maker sent ERC721 NFT payment, tx hash: {:02x}", maker_payment_to_refund.tx_hash() ); - let confirm_input = ConfirmPaymentInput { - payment_tx: maker_payment_to_refund.tx_hex(), - confirmations: 1, - requires_nota: false, - wait_until: now_sec() + 100, - check_every: 1, - }; - maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - + wait_for_confirmations(&setup.maker_global_nft, &maker_payment_to_refund, 90); let current_owner = geth_erc712_owner(U256::from(token_id)); assert_eq!(current_owner, geth_nft_maker_swap_v2()); - let refund_timelock_args = RefundNftMakerPaymentArgs { - maker_payment_tx: &maker_payment_to_refund, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - taker_secret, - swap_unique_data: &[], - contract_type: &ContractType::Erc721, - swap_contract_address: &geth_nft_maker_swap_v2(), - }; - let refund_timelock_tx = - block_on(maker_global_nft.refund_nft_maker_payment_v2_timelock(refund_timelock_args)).unwrap(); + let refund_timelock_tx = refund_nft_maker_payment( + &setup, + &maker_payment_to_refund, + &ContractType::Erc721, + RefundType::Timelock, + ); log!( "Maker refunded ERC721 NFT payment after timelock, tx hash: {:02x}", refund_timelock_tx.tx_hash() ); - let confirm_input = ConfirmPaymentInput { - payment_tx: refund_timelock_tx.tx_hex(), - confirmations: 1, - requires_nota: false, - wait_until: now_sec() + 100, - check_every: 1, - }; - maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + wait_for_confirmations(&setup.maker_global_nft, &refund_timelock_tx, 90); let current_owner = geth_erc712_owner(U256::from(token_id)); + let maker_address = block_on(setup.maker_global_nft.my_addr()); assert_eq!(current_owner, maker_address); } #[test] fn send_and_refund_erc1155_maker_payment_timelock() { - let token_id = 3u32; + let token_id = 2u32; let amount = 3u32; - let erc1155_nft = TestNftType::Erc1155 { token_id, amount }; - - let maker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), Some(erc1155_nft)); - let taker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), None); - - let maker_address = block_on(maker_global_nft.my_addr()); - let time_lock_to_refund = now_sec() - 1000; - let taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); - - let maker_secret = &[1; 32]; - let maker_secret_hash = sha256(maker_secret).to_vec(); - let taker_secret = &[0; 32]; - let taker_secret_hash = sha256(taker_secret).to_vec(); - - let nft_swap_info = NftSwapInfo { - token_address: &geth_erc1155_contract(), - token_id: &BigUint::from(token_id).to_bytes(), - contract_type: &ContractType::Erc1155, - swap_contract_address: &geth_nft_maker_swap_v2(), - }; + let setup = setup_test( + token_id, + Some(amount), + ContractType::Erc1155, + geth_nft_maker_swap_v2(), + geth_erc1155_contract(), + time_lock_to_refund, + ); - let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { - time_lock: time_lock_to_refund, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - amount: amount.into(), - taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), - swap_unique_data: &[], - nft_swap_info: &nft_swap_info, - }; - let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); + let maker_payment_to_refund = send_nft_maker_payment(&setup, amount.into()); log!( "Maker sent ERC1155 NFT payment, tx hash: {:02x}", maker_payment_to_refund.tx_hash() ); - let confirm_input = ConfirmPaymentInput { - payment_tx: maker_payment_to_refund.tx_hex(), - confirmations: 1, - requires_nota: false, - wait_until: now_sec() + 70, - check_every: 1, - }; - maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - + wait_for_confirmations(&setup.maker_global_nft, &maker_payment_to_refund, 70); let balance = geth_erc1155_balance(geth_nft_maker_swap_v2(), U256::from(token_id)); assert_eq!(U256::from(amount), balance); - let refund_timelock_args = RefundNftMakerPaymentArgs { - maker_payment_tx: &maker_payment_to_refund, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - taker_secret, - swap_unique_data: &[], - contract_type: &ContractType::Erc1155, - swap_contract_address: &geth_nft_maker_swap_v2(), - }; - let refund_timelock_tx = - block_on(maker_global_nft.refund_nft_maker_payment_v2_timelock(refund_timelock_args)).unwrap(); + let refund_timelock_tx = refund_nft_maker_payment( + &setup, + &maker_payment_to_refund, + &ContractType::Erc1155, + RefundType::Timelock, + ); log!( "Maker refunded ERC1155 NFT payment after timelock, tx hash: {:02x}", refund_timelock_tx.tx_hash() ); - let confirm_input = ConfirmPaymentInput { - payment_tx: refund_timelock_tx.tx_hex(), - confirmations: 1, - requires_nota: false, - wait_until: now_sec() + 70, - check_every: 1, - }; - maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + wait_for_confirmations(&setup.maker_global_nft, &refund_timelock_tx, 70); + let maker_address = block_on(setup.maker_global_nft.my_addr()); let balance = geth_erc1155_balance(maker_address, U256::from(token_id)); assert_eq!(U256::from(amount), balance); } #[test] fn send_and_refund_erc721_maker_payment_secret() { - let token_id = 4u32; - let erc721_nft = TestNftType::Erc721 { token_id }; - - let maker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), Some(erc721_nft)); - let taker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), None); - - let maker_address = block_on(maker_global_nft.my_addr()); - + let token_id = 3u32; let time_lock_to_refund = now_sec() + 1000; - let taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); - - let maker_secret = &[1; 32]; - let maker_secret_hash = sha256(maker_secret).to_vec(); - let taker_secret = &[0; 32]; - let taker_secret_hash = sha256(taker_secret).to_vec(); - let nft_swap_info = NftSwapInfo { - token_address: &geth_erc721_contract(), - token_id: &BigUint::from(token_id).to_bytes(), - contract_type: &ContractType::Erc721, - swap_contract_address: &geth_nft_maker_swap_v2(), - }; + let setup = setup_test( + token_id, + None, + ContractType::Erc721, + geth_nft_maker_swap_v2(), + geth_erc721_contract(), + time_lock_to_refund, + ); - let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { - time_lock: time_lock_to_refund, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - amount: 1.into(), - taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), - swap_unique_data: &[], - nft_swap_info: &nft_swap_info, - }; - let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); + let maker_payment_to_refund = send_nft_maker_payment(&setup, 1.into()); log!( "Maker sent ERC721 NFT payment, tx hash: {:02x}", maker_payment_to_refund.tx_hash() ); - let confirm_input = ConfirmPaymentInput { - payment_tx: maker_payment_to_refund.tx_hex(), - confirmations: 1, - requires_nota: false, - wait_until: now_sec() + 100, - check_every: 1, - }; - maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); - + wait_for_confirmations(&setup.maker_global_nft, &maker_payment_to_refund, 80); let current_owner = geth_erc712_owner(U256::from(token_id)); assert_eq!(current_owner, geth_nft_maker_swap_v2()); - let refund_secret_args = RefundNftMakerPaymentArgs { - maker_payment_tx: &maker_payment_to_refund, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - taker_secret, - swap_unique_data: &[], - contract_type: &ContractType::Erc721, - swap_contract_address: &geth_nft_maker_swap_v2(), - }; - let refund_secret_tx = block_on(maker_global_nft.refund_nft_maker_payment_v2_secret(refund_secret_args)).unwrap(); + let refund_secret_tx = refund_nft_maker_payment( + &setup, + &maker_payment_to_refund, + &ContractType::Erc721, + RefundType::Secret, + ); log!( "Maker refunded ERC721 NFT payment using Taker secret, tx hash: {:02x}", refund_secret_tx.tx_hash() ); - let confirm_input = ConfirmPaymentInput { - payment_tx: refund_secret_tx.tx_hex(), - confirmations: 1, - requires_nota: false, - wait_until: now_sec() + 100, - check_every: 1, - }; - maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + wait_for_confirmations(&setup.maker_global_nft, &refund_secret_tx, 80); let current_owner = geth_erc712_owner(U256::from(token_id)); + let maker_address = block_on(setup.maker_global_nft.my_addr()); assert_eq!(current_owner, maker_address); } #[test] fn send_and_refund_erc1155_maker_payment_secret() { - let token_id = 4u32; + let token_id = 3u32; let amount = 3u32; - let erc1155_nft = TestNftType::Erc1155 { token_id, amount }; + let time_lock_to_refund = now_sec() + 1000; - let maker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), Some(erc1155_nft)); - let taker_global_nft = global_nft_with_random_privkey(geth_nft_maker_swap_v2(), None); + let setup = setup_test( + token_id, + Some(amount), + ContractType::Erc1155, + geth_nft_maker_swap_v2(), + geth_erc1155_contract(), + time_lock_to_refund, + ); - let maker_address = block_on(maker_global_nft.my_addr()); + let maker_payment_to_refund = send_nft_maker_payment(&setup, amount.into()); + log!( + "Maker sent ERC1155 NFT payment, tx hash: {:02x}", + maker_payment_to_refund.tx_hash() + ); - let time_lock_to_refund = now_sec() - 1000; - let taker_pubkey = taker_global_nft.derive_htlc_pubkey(&[]); + wait_for_confirmations(&setup.maker_global_nft, &maker_payment_to_refund, 70); + let balance = geth_erc1155_balance(geth_nft_maker_swap_v2(), U256::from(token_id)); + assert_eq!(U256::from(amount), balance); - let maker_secret = &[1; 32]; - let maker_secret_hash = sha256(maker_secret).to_vec(); - let taker_secret = &[0; 32]; - let taker_secret_hash = sha256(taker_secret).to_vec(); + let refund_secret_tx = refund_nft_maker_payment( + &setup, + &maker_payment_to_refund, + &ContractType::Erc1155, + RefundType::Secret, + ); + log!( + "Maker refunded ERC1155 NFT payment using Taker secret, tx hash: {:02x}", + refund_secret_tx.tx_hash() + ); - let nft_swap_info = NftSwapInfo { - token_address: &geth_erc1155_contract(), - token_id: &BigUint::from(token_id).to_bytes(), - contract_type: &ContractType::Erc1155, - swap_contract_address: &geth_nft_maker_swap_v2(), + wait_for_confirmations(&setup.maker_global_nft, &refund_secret_tx, 70); + let maker_address = block_on(setup.maker_global_nft.my_addr()); + let balance = geth_erc1155_balance(maker_address, U256::from(token_id)); + assert_eq!(U256::from(amount), balance); +} + +struct NftTestSetup { + maker_global_nft: EthCoin, + taker_global_nft: EthCoin, + nft_swap_info: TestNftSwapInfo, + maker_secret: Vec, + maker_secret_hash: Vec, + taker_secret: Vec, + taker_secret_hash: Vec, + time_lock: u64, +} + +/// Structure representing necessary NFT info for Swap +pub struct TestNftSwapInfo { + /// The address of the NFT token + pub token_address: Coin::ContractAddress, + /// The ID of the NFT token. + pub token_id: Vec, + /// The type of smart contract that governs this NFT + pub contract_type: Coin::ContractType, + /// Etomic swap contract address + pub swap_contract_address: Coin::ContractAddress, +} + +fn setup_test( + token_id: u32, + amount: Option, + contract_type: ContractType, + nft_swap_contract: Address, + token_contract: Address, + time_lock: u64, +) -> NftTestSetup { + let nft_type = match contract_type { + ContractType::Erc721 => TestNftType::Erc721 { token_id }, + ContractType::Erc1155 => TestNftType::Erc1155 { + token_id, + amount: amount.unwrap(), + }, + }; + + let maker_global_nft = global_nft_with_random_privkey(nft_swap_contract, Some(nft_type)); + let taker_global_nft = global_nft_with_random_privkey(nft_swap_contract, None); + let maker_secret = vec![1; 32]; + let maker_secret_hash = sha256(&maker_secret).to_vec(); + let taker_secret = vec![0; 32]; + let taker_secret_hash = sha256(&taker_secret).to_vec(); + + let token_id = BigUint::from(token_id).to_bytes(); + + let nft_swap_info = TestNftSwapInfo { + token_address: token_contract, + token_id, + contract_type, + swap_contract_address, }; - let send_payment_args: SendNftMakerPaymentArgs = SendNftMakerPaymentArgs { - time_lock: time_lock_to_refund, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - amount: amount.into(), - taker_pub: &taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), + NftTestSetup { + maker_global_nft, + taker_global_nft, + nft_swap_info, + maker_secret, + maker_secret_hash, + taker_secret, + taker_secret_hash, + time_lock, + } +} + +fn send_nft_maker_payment(setup: &NftTestSetup, amount: BigDecimal) -> SignedEthTx { + let taker_pubkey = setup.taker_global_nft.derive_htlc_pubkey(&[]); + let nft_swap_info = NftSwapInfo { + token_address: &setup.nft_swap_info.token_address, + token_id: &setup.nft_swap_info.token_id, + contract_type: &setup.nft_swap_info.contract_type, + swap_contract_address: &setup.nft_swap_info.swap_contract_address, + }; + let send_payment_args = SendNftMakerPaymentArgs:: { + time_lock: setup.time_lock, + taker_secret_hash: &setup.taker_secret_hash, + maker_secret_hash: &setup.maker_secret_hash, + amount, + taker_pub: &setup.taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), swap_unique_data: &[], nft_swap_info: &nft_swap_info, }; - let maker_payment_to_refund = block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); - log!( - "Maker sent ERC1155 NFT payment, tx hash: {:02x}", - maker_payment_to_refund.tx_hash() - ); + block_on(setup.maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap() +} +fn wait_for_confirmations(global_nft: &EthCoin, tx: &SignedEthTx, wait_seconds: u64) { let confirm_input = ConfirmPaymentInput { - payment_tx: maker_payment_to_refund.tx_hex(), + payment_tx: tx.tx_hex(), confirmations: 1, requires_nota: false, - wait_until: now_sec() + 70, + wait_until: now_sec() + wait_seconds, check_every: 1, }; - maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); +} - let balance = geth_erc1155_balance(geth_nft_maker_swap_v2(), U256::from(token_id)); - assert_eq!(U256::from(amount), balance); +fn validate_nft_maker_payment(setup: &NftTestSetup, maker_payment: &SignedEthTx, amount: BigDecimal) { + let maker_pubkey = setup.maker_global_nft.derive_htlc_pubkey(&[]); + let taker_pubkey = setup.taker_global_nft.derive_htlc_pubkey(&[]); + let validate_args = ValidateNftMakerPaymentArgs { + maker_payment_tx: maker_payment, + time_lock: setup.time_lock, + taker_secret_hash: &setup.taker_secret_hash, + maker_secret_hash: &setup.maker_secret_hash, + amount, + taker_pub: &setup.taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), + maker_pub: &setup.maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), + swap_unique_data: &[], + nft_swap_info: &setup.nft_swap_info, + }; + block_on(setup.maker_global_nft.validate_nft_maker_payment_v2(validate_args)).unwrap() +} - let refund_secret_args = RefundNftMakerPaymentArgs { - maker_payment_tx: &maker_payment_to_refund, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - taker_secret, +fn spend_nft_maker_payment( + setup: &NftTestSetup, + maker_payment: &SignedEthTx, + contract_type: &ContractType, +) -> SignedEthTx { + let spend_payment_args = SpendNftMakerPaymentArgs { + maker_payment_tx: maker_payment, + taker_secret_hash: &setup.taker_secret_hash, + maker_secret_hash: &setup.maker_secret_hash, + maker_secret: &setup.maker_secret, + maker_pub: &setup + .maker_global_nft + .parse_pubkey(&setup.maker_global_nft.derive_htlc_pubkey(&[])) + .unwrap(), swap_unique_data: &[], - contract_type: &ContractType::Erc1155, - swap_contract_address: &geth_nft_maker_swap_v2(), + contract_type, + swap_contract_address: &setup.nft_swap_info.swap_contract_address, }; - let refund_secret_tx = block_on(maker_global_nft.refund_nft_maker_payment_v2_secret(refund_secret_args)).unwrap(); - log!( - "Maker refunded ERC1155 NFT payment using Taker secret, tx hash: {:02x}", - refund_secret_tx.tx_hash() - ); - let confirm_input = ConfirmPaymentInput { - payment_tx: refund_secret_tx.tx_hex(), - confirmations: 1, - requires_nota: false, - wait_until: now_sec() + 70, - check_every: 1, + block_on(setup.taker_global_nft.spend_nft_maker_payment_v2(spend_payment_args)).unwrap() +} + +fn refund_nft_maker_payment( + setup: &NftTestSetup, + maker_payment: &SignedEthTx, + contract_type: &ContractType, + refund_type: RefundType, +) -> SignedEthTx { + let refund_args = RefundNftMakerPaymentArgs { + maker_payment_tx: maker_payment, + taker_secret_hash: &setup.taker_secret_hash, + maker_secret_hash: &setup.maker_secret_hash, + taker_secret: &setup.taker_secret, + swap_unique_data: &[], + contract_type, + swap_contract_address: &setup.nft_swap_info.swap_contract_address, }; - maker_global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + match refund_type { + RefundType::Timelock => { + block_on(setup.maker_global_nft.refund_nft_maker_payment_v2_timelock(refund_args)).unwrap() + }, + RefundType::Secret => block_on(setup.maker_global_nft.refund_nft_maker_payment_v2_secret(refund_args)).unwrap(), + } +} - let balance = geth_erc1155_balance(maker_address, U256::from(token_id)); - assert_eq!(U256::from(amount), balance); +enum RefundType { + Timelock, + Secret, } From f789e9188152af97f96f8ad62b95a5ad427daab0 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 30 May 2024 20:14:16 +0700 Subject: [PATCH 050/233] provide NftSwapInfo type --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 19ef7f2405..b5b60351e6 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1232,7 +1232,7 @@ fn setup_test( token_address: token_contract, token_id, contract_type, - swap_contract_address, + swap_contract_address: nft_swap_contract, }; NftTestSetup { @@ -1281,6 +1281,12 @@ fn wait_for_confirmations(global_nft: &EthCoin, tx: &SignedEthTx, wait_seconds: fn validate_nft_maker_payment(setup: &NftTestSetup, maker_payment: &SignedEthTx, amount: BigDecimal) { let maker_pubkey = setup.maker_global_nft.derive_htlc_pubkey(&[]); let taker_pubkey = setup.taker_global_nft.derive_htlc_pubkey(&[]); + let nft_swap_info = NftSwapInfo { + token_address: &setup.nft_swap_info.token_address, + token_id: &setup.nft_swap_info.token_id, + contract_type: &setup.nft_swap_info.contract_type, + swap_contract_address: &setup.nft_swap_info.swap_contract_address, + }; let validate_args = ValidateNftMakerPaymentArgs { maker_payment_tx: maker_payment, time_lock: setup.time_lock, @@ -1290,7 +1296,7 @@ fn validate_nft_maker_payment(setup: &NftTestSetup, maker_payment: &SignedEthTx, taker_pub: &setup.taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), maker_pub: &setup.maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), swap_unique_data: &[], - nft_swap_info: &setup.nft_swap_info, + nft_swap_info: &nft_swap_info, }; block_on(setup.maker_global_nft.validate_nft_maker_payment_v2(validate_args)).unwrap() } From aa1d70fad79e3bbe330f77483c08e70d89af647a Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 31 May 2024 18:29:47 +0700 Subject: [PATCH 051/233] use coins config file for NFT activation --- mm2src/coins/eth/v2_activation.rs | 30 ++++++++++++++-- .../src/erc20_token_activation.rs | 14 +++++++- .../src/eth_with_token_activation.rs | 2 +- mm2src/coins_activation/src/prelude.rs | 34 +++++-------------- 4 files changed, 50 insertions(+), 30 deletions(-) diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 37768402e7..d1e77e1435 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -477,7 +477,7 @@ impl EthCoin { /// It fetches NFT details from a given URL to populate the `nfts_infos` field, which stores information about the user's NFTs. /// /// This setup allows the Global NFT to function like a coin, supporting swap operations and providing easy access to NFT details via `nfts_infos`. - pub async fn global_nft_from_platform_coin( + pub async fn initialize_global_nft( &self, original_url: &Url, proxy_auth: &bool, @@ -491,6 +491,30 @@ impl EthCoin { let conf = coin_conf(&ctx, &ticker); + let web3_instances: Vec = self + .web3_instances + .lock() + .await + .iter() + .map(|node| { + let mut transport = node.web3.transport().clone(); + if let Some(auth) = transport.proxy_auth_validation_generator_as_mut() { + auth.coin_ticker = ticker.clone(); + } + let web3 = Web3::new(transport); + Web3Instance { + web3, + is_parity: node.is_parity, + } + }) + .collect(); + + let required_confirmations = AtomicU64::new( + conf["required_confirmations"] + .as_u64() + .unwrap_or_else(|| self.required_confirmations.load(Ordering::Relaxed)), + ); + // Create an abortable system linked to the `platform_coin` (which is self) so if the platform coin is disabled, // all spawned futures related to global Non-Fungible Token will be aborted as well. let abortable_system = self.abortable_system.create_subsystem()?; @@ -518,12 +542,12 @@ impl EthCoin { swap_contract_address: self.swap_contract_address, fallback_swap_contract: self.fallback_swap_contract, contract_supports_watchers: self.contract_supports_watchers, - web3_instances: self.web3_instances.lock().await.clone().into(), + web3_instances: AsyncMutex::new(web3_instances), decimals: self.decimals, history_sync_state: Mutex::new(self.history_sync_state.lock().unwrap().clone()), swap_txfee_policy: Mutex::new(SwapTxFeePolicy::Internal), max_eth_tx_type, - required_confirmations: AtomicU64::new(self.required_confirmations.load(Ordering::Relaxed)), + required_confirmations, ctx: self.ctx.clone(), chain_id: self.chain_id, trezor_coin: self.trezor_coin.clone(), diff --git a/mm2src/coins_activation/src/erc20_token_activation.rs b/mm2src/coins_activation/src/erc20_token_activation.rs index 82b89026bb..8ce240b8a5 100644 --- a/mm2src/coins_activation/src/erc20_token_activation.rs +++ b/mm2src/coins_activation/src/erc20_token_activation.rs @@ -81,6 +81,18 @@ impl TryFromCoinProtocol for Erc20Protocol { } } +impl TryFromCoinProtocol for NftProtocol { + fn try_from_coin_protocol(proto: CoinProtocol) -> Result> + where + Self: Sized, + { + match proto { + CoinProtocol::NFT { platform } => Ok(NftProtocol { platform }), + proto => MmError::err(proto), + } + } +} + impl TryFromCoinProtocol for EthTokenProtocol { fn try_from_coin_protocol(proto: CoinProtocol) -> Result> where @@ -165,7 +177,7 @@ impl TokenActivationOps for EthCoin { } let nft_global = match &nft_init_params.provider { NftProviderEnum::Moralis { url, proxy_auth } => { - platform_coin.global_nft_from_platform_coin(url, proxy_auth).await? + platform_coin.initialize_global_nft(url, proxy_auth).await? }, }; let nfts = nft_global.nfts_infos.lock().await.clone(); diff --git a/mm2src/coins_activation/src/eth_with_token_activation.rs b/mm2src/coins_activation/src/eth_with_token_activation.rs index 487745419a..acb791a2d5 100644 --- a/mm2src/coins_activation/src/eth_with_token_activation.rs +++ b/mm2src/coins_activation/src/eth_with_token_activation.rs @@ -295,7 +295,7 @@ impl PlatformCoinWithTokensActivationOps for EthCoin { }, None => return Ok(None), }; - let nft_global = self.global_nft_from_platform_coin(url, proxy_auth).await?; + let nft_global = self.initialize_global_nft(url, proxy_auth).await?; Ok(Some(MmCoinEnum::EthCoin(nft_global))) } diff --git a/mm2src/coins_activation/src/prelude.rs b/mm2src/coins_activation/src/prelude.rs index 36fe5aa43b..236d19b1c1 100644 --- a/mm2src/coins_activation/src/prelude.rs +++ b/mm2src/coins_activation/src/prelude.rs @@ -1,4 +1,3 @@ -use coins::nft::nft_structs::{Chain, ConvertChain}; #[cfg(feature = "enable-sia")] use coins::sia::SiaCoinActivationParams; use coins::utxo::UtxoActivationParams; @@ -75,37 +74,22 @@ pub fn coin_conf_with_protocol( ctx: &MmArc, coin: &str, ) -> Result<(Json, T), MmError> { - let (conf, coin_protocol) = match Chain::from_nft_ticker(coin) { - Ok(chain) => { - let platform = chain.to_ticker(); - let platform_conf = coin_conf(ctx, platform); - let nft_protocol = CoinProtocol::NFT { - platform: platform.to_string(), - }; - (platform_conf, nft_protocol) - }, - Err(_) => { - let conf = coin_conf(ctx, coin); - let coin_protocol: CoinProtocol = json::from_value(conf["protocol"].clone()).map_to_mm(|err| { - CoinConfWithProtocolError::CoinProtocolParseError { - ticker: coin.into(), - err, - } - })?; - (conf, coin_protocol) - }, - }; - + let conf = coin_conf(ctx, coin); if conf.is_null() { return MmError::err(CoinConfWithProtocolError::ConfigIsNotFound(coin.into())); } - - let protocol = + let coin_protocol: CoinProtocol = json::from_value(conf["protocol"].clone()).map_to_mm(|err| { + CoinConfWithProtocolError::CoinProtocolParseError { + ticker: coin.into(), + err, + } + })?; + let coin_protocol = T::try_from_coin_protocol(coin_protocol).mm_err(|protocol| CoinConfWithProtocolError::UnexpectedProtocol { ticker: coin.into(), protocol, })?; - Ok((conf, protocol)) + Ok((conf, coin_protocol)) } /// A trait to be implemented for coin activation requests to determine some information about the request. From b9f2a98f11c8006c98412d3e23e70752b3a02acc Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 2 Jun 2024 11:40:35 +0700 Subject: [PATCH 052/233] reduce code duplication using `validate_state` func --- mm2src/coins/eth/nft_swap_v2/mod.rs | 36 ++++++++++++----------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index 7bef8ae01d..30788634b0 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -336,13 +336,7 @@ impl EthCoin { htlc_params: Vec, state: U256, ) -> Result, PrepareTxDataError> { - if state != U256::from(MakerPaymentStateV2::PaymentSent as u8) { - return Err(PrepareTxDataError::Internal(ERRL!( - "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", - args.maker_payment_tx, - state - ))); - } + validate_state(args.maker_payment_tx, state, MakerPaymentStateV2::PaymentSent as u8)?; let spend_func = match args.contract_type { ContractType::Erc1155 => NFT_MAKER_SWAP_V2.function("spendErc1155MakerPayment")?, @@ -380,13 +374,7 @@ impl EthCoin { htlc_params: Vec, state: U256, ) -> Result, PrepareTxDataError> { - if state != U256::from(MakerPaymentStateV2::PaymentSent as u8) { - return Err(PrepareTxDataError::Internal(ERRL!( - "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", - args.maker_payment_tx, - state - ))); - } + validate_state(args.maker_payment_tx, state, MakerPaymentStateV2::PaymentSent as u8)?; let refund_func = match args.contract_type { ContractType::Erc1155 => NFT_MAKER_SWAP_V2.function("refundErc1155MakerPaymentTimelock")?, @@ -423,13 +411,7 @@ impl EthCoin { htlc_params: Vec, state: U256, ) -> Result, PrepareTxDataError> { - if state != U256::from(MakerPaymentStateV2::PaymentSent as u8) { - return Err(PrepareTxDataError::Internal(ERRL!( - "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", - args.maker_payment_tx, - state - ))); - } + validate_state(args.maker_payment_tx, state, MakerPaymentStateV2::PaymentSent as u8)?; let refund_func = match args.contract_type { ContractType::Erc1155 => NFT_MAKER_SWAP_V2.function("refundErc1155MakerPaymentSecret")?, @@ -693,3 +675,15 @@ fn erc721_transfer_with_data<'a>() -> Result<&'a ethabi::Function, Erc721Functio })?; Ok(function) } + +fn validate_state(tx: &SignedEthTx, state: U256, expected_state: u8) -> Result<(), PrepareTxDataError> { + if state != U256::from(expected_state) { + return Err(PrepareTxDataError::Internal(ERRL!( + "Payment {:?} state is not {}, got {}", + tx, + expected_state, + state + ))); + } + Ok(()) +} From ece51528a35e4cbd24de09c1eb96160f3accb148 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 4 Jun 2024 19:59:30 +0700 Subject: [PATCH 053/233] refactor Quicknode HTTP request: move `signed_message` to header --- mm2src/coins/eth.rs | 2 +- mm2src/coins/eth/v2_activation.rs | 5 +- .../eth/web3_transport/http_transport.rs | 72 ++++++++++++------- mm2src/coins/eth/web3_transport/mod.rs | 40 ++++++++--- mm2src/coins/nft.rs | 8 +-- 5 files changed, 82 insertions(+), 45 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 8495b1dd28..15af146bff 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -344,11 +344,11 @@ type GasDetails = (U256, PayForGasOption); pub enum Web3RpcError { #[display(fmt = "Transport: {}", _0)] Transport(String), - #[from_stringify("serde_json::Error")] #[display(fmt = "Invalid response: {}", _0)] InvalidResponse(String), #[display(fmt = "Timeout: {}", _0)] Timeout(String), + #[from_stringify("serde_json::Error")] #[display(fmt = "Internal: {}", _0)] Internal(String), #[display(fmt = "Invalid gas api provider config: {}", _0)] diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index d1e77e1435..486f025c9e 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -523,8 +523,7 @@ impl EthCoin { let my_address = self.derivation_method.single_addr_or_err().await?; let my_address_str = display_eth_address(&my_address); - let signed_message = - generate_signed_message(*proxy_auth, &chain, my_address_str, self.priv_key_policy()).await?; + let signed_message = nft_signed_message(*proxy_auth, &chain, my_address_str, self.priv_key_policy()).await?; let nft_infos = get_nfts_for_activation(&chain, &my_address, original_url, signed_message.as_ref()).await?; let coin_type = EthCoinType::Nft { @@ -562,7 +561,7 @@ impl EthCoin { } } -pub(crate) async fn generate_signed_message( +pub(crate) async fn nft_signed_message( proxy_auth: bool, chain: &Chain, my_address: String, diff --git a/mm2src/coins/eth/web3_transport/http_transport.rs b/mm2src/coins/eth/web3_transport/http_transport.rs index 463e2455fa..09cdb24b43 100644 --- a/mm2src/coins/eth/web3_transport/http_transport.rs +++ b/mm2src/coins/eth/web3_transport/http_transport.rs @@ -1,6 +1,6 @@ -use crate::eth::web3_transport::handle_quicknode_payload; +use crate::eth::web3_transport::generate_auth_header; use crate::eth::{web3_transport::Web3SendOut, RpcTransportEventHandler, RpcTransportEventHandlerShared, Web3RpcError}; -use common::APPLICATION_JSON; +use common::{APPLICATION_JSON, X_AUTH_PAYLOAD}; use http::header::CONTENT_TYPE; use jsonrpc_core::{Call, Response}; use mm2_net::transport::{KomodefiProxyAuthValidation, ProxyAuthValidationGenerator}; @@ -108,16 +108,14 @@ async fn send_request(request: Call, transport: HttpTransport) -> Result serialized_request = r, - Err(e) => { - return Err(request_failed_error(request, e)); - }, - }; - } + let auth_header = match generate_auth_header(&transport.proxy_auth_validation_generator, transport.node.gui_auth) { + Ok(signed_message) => signed_message, + Err(e) => { + return Err(request_failed_error(request, e)); + }, + }; transport .event_handlers @@ -126,6 +124,17 @@ async fn send_request(request: Call, transport: HttpTransport) -> Result { + req.headers_mut().insert(X_AUTH_PAYLOAD, header_value); + }, + Err(e) => { + return Err(request_failed_error(request, Web3RpcError::Internal(e.to_string()))); + }, + } + } req.headers_mut() .insert(CONTENT_TYPE, HeaderValue::from_static(APPLICATION_JSON)); let timeout = Timer::sleep(REQUEST_TIMEOUT_S); @@ -184,21 +193,26 @@ async fn send_request(request: Call, transport: HttpTransport) -> Result Result { - let mut serialized_request = to_string(&request); + let serialized_request = to_string(&request); - if transport.node.gui_auth { - match handle_quicknode_payload(&transport.proxy_auth_validation_generator, &request) { - Ok(r) => serialized_request = r, - Err(e) => { - return Err(request_failed_error( - request, - Web3RpcError::Transport(format!("Server: '{}', error: {}", transport.node.uri, e)), - )); - }, - }; - } + let auth_header = match generate_auth_header(&transport.proxy_auth_validation_generator, transport.node.gui_auth) { + Ok(signed_message) => signed_message, + Err(e) => { + return Err(request_failed_error( + request, + Web3RpcError::Transport(format!("Server: '{}', error: {}", transport.node.uri, e)), + )); + }, + }; - match send_request_once(serialized_request, &transport.node.uri, &transport.event_handlers).await { + match send_request_once( + serialized_request, + &transport.node.uri, + &transport.event_handlers, + auth_header, + ) + .await + { Ok(response_json) => Ok(response_json), Err(Error::Transport(e)) => Err(request_failed_error( request, @@ -216,6 +230,7 @@ async fn send_request_once( request_payload: String, uri: &http::Uri, event_handlers: &Vec, + auth_header: Option, ) -> Result { use http::header::ACCEPT; use mm2_net::wasm::http::FetchRequest; @@ -223,11 +238,16 @@ async fn send_request_once( // account for outgoing traffic event_handlers.on_outgoing_request(request_payload.as_bytes()); - let (status_code, response_str) = FetchRequest::post(&uri.to_string()) + let mut fetch_request = FetchRequest::post(&uri.to_string()) .cors() .body_utf8(request_payload) .header(ACCEPT.as_str(), APPLICATION_JSON) - .header(CONTENT_TYPE.as_str(), APPLICATION_JSON) + .header(CONTENT_TYPE.as_str(), APPLICATION_JSON); + // Insert auth header if present + if let Some(auth_value) = auth_header { + fetch_request = fetch_request.header(X_AUTH_PAYLOAD, &auth_value); + } + let (status_code, response_str) = fetch_request .request_str() .await .map_err(|e| Error::Transport(TransportError::Message(ERRL!("{:?}", e))))?; diff --git a/mm2src/coins/eth/web3_transport/mod.rs b/mm2src/coins/eth/web3_transport/mod.rs index 421c9349a8..7cbd70e81b 100644 --- a/mm2src/coins/eth/web3_transport/mod.rs +++ b/mm2src/coins/eth/web3_transport/mod.rs @@ -2,7 +2,7 @@ use ethereum_types::U256; use futures::future::BoxFuture; use jsonrpc_core::Call; #[cfg(target_arch = "wasm32")] use mm2_metamask::MetamaskResult; -use mm2_net::transport::ProxyAuthValidationGenerator; +use mm2_net::transport::{KomodefiProxyAuthValidation, ProxyAuthValidationGenerator}; use serde_json::Value as Json; use serde_json::Value; use std::sync::atomic::Ordering; @@ -134,14 +134,40 @@ pub struct FeeHistoryResult { pub priority_rewards: Option>>, } -/// Generates a signed message and inserts it into the request payload. +/// Generates a Quicknode payload JSON string by inserting a signed message into the request payload. pub(super) fn handle_quicknode_payload( proxy_auth_validation_generator: &Option, request: &Call, ) -> Result { + let signed_message = generate_signed_message(proxy_auth_validation_generator)?; + + let auth_request = QuicknodePayload { + request, + signed_message, + }; + + Ok(to_string(&auth_request)) +} + +/// Generates a signed message JSON string if proxy authentication is enabled. +pub(crate) fn generate_auth_header( + proxy_auth_validation_generator: &Option, + gui_auth: bool, +) -> Result, Web3RpcError> { + if !gui_auth { + return Ok(None); + } + let signed_message = generate_signed_message(proxy_auth_validation_generator)?; + Ok(Some(serde_json::to_string(&signed_message)?)) +} + +/// Generates a signed message using the provided ProxyAuthValidationGenerator +fn generate_signed_message( + proxy_auth_validation_generator: &Option, +) -> Result { let generator = proxy_auth_validation_generator .clone() - .ok_or_else(|| Web3RpcError::Internal("ProxyAuthValidationGenerator is not provided for".to_string()))?; + .ok_or_else(|| Web3RpcError::Internal("ProxyAuthValidationGenerator is not provided".to_string()))?; let signed_message = EthCoin::generate_proxy_auth_signed_validation(generator).map_err(|e| { Web3RpcError::Internal(format!( @@ -149,11 +175,5 @@ pub(super) fn handle_quicknode_payload( e )) })?; - - let auth_request = QuicknodePayload { - request, - signed_message, - }; - - Ok(to_string(&auth_request)) + Ok(signed_message) } diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index 4d432235a9..50267b96a1 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -42,7 +42,7 @@ use web3::types::TransactionId; #[cfg(not(target_arch = "wasm32"))] use mm2_net::native_http::send_request_to_uri; -use crate::eth::v2_activation::generate_signed_message; +use crate::eth::v2_activation::nft_signed_message; #[cfg(target_arch = "wasm32")] use mm2_net::wasm::http::send_request_to_uri; @@ -238,8 +238,7 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft }, }; let my_address = eth_coin.my_address()?; - let signed_message = - generate_signed_message(req.proxy_auth, chain, my_address, ð_coin.priv_key_policy).await?; + let signed_message = nft_signed_message(req.proxy_auth, chain, my_address, ð_coin.priv_key_policy).await?; let wrapper = UrlSignWrapper { chain, orig_url: &req.url, @@ -474,8 +473,7 @@ pub async fn refresh_nft_metadata(ctx: MmArc, req: RefreshMetadataReq) -> MmResu }, }; let my_address = eth_coin.my_address()?; - let signed_message = - generate_signed_message(req.proxy_auth, &req.chain, my_address, ð_coin.priv_key_policy).await?; + let signed_message = nft_signed_message(req.proxy_auth, &req.chain, my_address, ð_coin.priv_key_policy).await?; let wrapper = UrlSignWrapper { chain: &req.chain, orig_url: &req.url, From 920861e0948a44f918c312c960903f77338f7534 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 5 Jun 2024 09:47:13 +0700 Subject: [PATCH 054/233] tests: increase wait for confirm time and add sleep duration --- .../tests/docker_tests/eth_docker_tests.rs | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index b5b60351e6..a718199f47 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -713,6 +713,7 @@ fn send_and_spend_eth_maker_payment_internal_gas_policy() { fn send_and_spend_eth_maker_payment_priority_fee() { send_and_spend_eth_maker_payment_impl(SwapTxFeePolicy::Medium); } fn send_and_refund_erc20_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { + thread::sleep(Duration::from_secs(10)); let erc20_coin = erc20_coin_with_random_privkey(swap_contract()); erc20_coin.set_swap_transaction_fee_policy(swap_txfee_policy); @@ -920,6 +921,7 @@ fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option Date: Fri, 7 Jun 2024 13:15:37 +0700 Subject: [PATCH 055/233] eth tpu v2: deploy maker and taker swap v2 contracts in tests. add maker_swap_v2_contract, taker_swap_v2_contract, nft_maker_swap_v2_contract in EthCoinImpl --- mm2src/coins/eth.rs | 25 + mm2src/coins/eth/eth_tests.rs | 4 + mm2src/coins/eth/eth_wasm_tests.rs | 4 +- mm2src/coins/eth/for_tests.rs | 3 + mm2src/coins/eth/maker_swap_v2_abi.json | 311 ++++++++++++ mm2src/coins/eth/taker_swap_v2_abi.json | 443 ++++++++++++++++++ mm2src/coins/eth/v2_activation.rs | 12 + .../tests/docker_tests/docker_tests_common.rs | 131 +++++- .../tests/docker_tests/docker_tests_inner.rs | 33 +- .../tests/docker_tests/eth_docker_tests.rs | 121 +++-- .../tests/docker_tests/swap_watcher_tests.rs | 81 ++-- mm2src/mm2_main/tests/mm2_tests/eth_tests.rs | 2 + .../tests/mm2_tests/mm2_tests_inner.rs | 8 + mm2src/mm2_test_helpers/src/for_tests.rs | 10 + 14 files changed, 1083 insertions(+), 105 deletions(-) create mode 100644 mm2src/coins/eth/maker_swap_v2_abi.json create mode 100644 mm2src/coins/eth/taker_swap_v2_abi.json diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 15af146bff..82fb3a57cd 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -173,6 +173,8 @@ const ERC721_ABI: &str = include_str!("eth/erc721_abi.json"); const ERC1155_ABI: &str = include_str!("eth/erc1155_abi.json"); const NFT_SWAP_CONTRACT_ABI: &str = include_str!("eth/nft_swap_contract_abi.json"); const NFT_MAKER_SWAP_V2_ABI: &str = include_str!("eth/nft_maker_swap_v2_abi.json"); +const MAKER_SWAP_V2_ABI: &str = include_str!("eth/maker_swap_v2_abi.json"); +const TAKER_SWAP_V2_ABI: &str = include_str!("eth/taker_swap_v2_abi.json"); /// Payment states from etomic swap smart contract: https://github.com/artemii235/etomic-swap/blob/master/contracts/EtomicSwap.sol#L5 pub enum PaymentState { @@ -258,6 +260,8 @@ const ETH_MAX_TX_TYPE: u64 = 0x7f; lazy_static! { pub static ref SWAP_CONTRACT: Contract = Contract::load(SWAP_CONTRACT_ABI.as_bytes()).unwrap(); + pub static ref MAKER_SWAP_V2: Contract = Contract::load(MAKER_SWAP_V2_ABI.as_bytes()).unwrap(); + pub static ref TAKER_SWAP_V2: Contract = Contract::load(TAKER_SWAP_V2_ABI.as_bytes()).unwrap(); pub static ref ERC20_CONTRACT: Contract = Contract::load(ERC20_ABI.as_bytes()).unwrap(); pub static ref ERC721_CONTRACT: Contract = Contract::load(ERC721_ABI.as_bytes()).unwrap(); pub static ref ERC1155_CONTRACT: Contract = Contract::load(ERC1155_ABI.as_bytes()).unwrap(); @@ -609,6 +613,9 @@ pub struct EthCoinImpl { derivation_method: Arc, sign_message_prefix: Option, swap_contract_address: Address, + maker_swap_v2_contract: Address, + taker_swap_v2_contract: Address, + nft_maker_swap_v2_contract: Option
, fallback_swap_contract: Option
, contract_supports_watchers: bool, web3_instances: AsyncMutex>, @@ -6218,6 +6225,21 @@ pub async fn eth_coin_from_conf_and_request( if swap_contract_address == Address::default() { return ERR!("swap_contract_address can't be zero address"); } + let maker_swap_v2_contract: Address = try_s!(json::from_value(req["maker_swap_v2_contract"].clone())); + if maker_swap_v2_contract == Address::default() { + return ERR!("maker_swap_v2_contract can't be zero address"); + } + let taker_swap_v2_contract: Address = try_s!(json::from_value(req["taker_swap_v2_contract"].clone())); + if taker_swap_v2_contract == Address::default() { + return ERR!("taker_swap_v2_contract can't be zero address"); + } + let nft_maker_swap_v2_contract: Option
= + try_s!(json::from_value(req["nft_maker_swap_v2_contract"].clone())); + if let Some(nft_maker_swap_v2) = nft_maker_swap_v2_contract { + if nft_maker_swap_v2 == Address::default() { + return ERR!("nft_maker_swap_v2_contract can't be zero address"); + } + } let fallback_swap_contract: Option
= try_s!(json::from_value(req["fallback_swap_contract"].clone())); if let Some(fallback) = fallback_swap_contract { if fallback == Address::default() { @@ -6371,6 +6393,9 @@ pub async fn eth_coin_from_conf_and_request( coin_type, sign_message_prefix, swap_contract_address, + maker_swap_v2_contract, + taker_swap_v2_contract, + nft_maker_swap_v2_contract, fallback_swap_contract, contract_supports_watchers, decimals, diff --git a/mm2src/coins/eth/eth_tests.rs b/mm2src/coins/eth/eth_tests.rs index 4d8b97c493..e378d5cbc2 100644 --- a/mm2src/coins/eth/eth_tests.rs +++ b/mm2src/coins/eth/eth_tests.rs @@ -788,6 +788,8 @@ fn polygon_check_if_my_payment_sent() { "coin": "MATIC", "urls": ["https://polygon-mainnet.g.alchemy.com/v2/9YYl6iMLmXXLoflMPHnMTC4Dcm2L2tFH"], "swap_contract_address": "0x9130b257d37a52e52f21054c4da3450c72f595ce", + "maker_swap_v2_contract": "0x9130b257d37a52e52f21054c4da3450c72f595ce", + "taker_swap_v2_contract": "0x9130b257d37a52e52f21054c4da3450c72f595ce", }); let priv_key_policy = PrivKeyBuildPolicy::IguanaPrivKey(IguanaPrivKey::from([1; 32])); @@ -940,6 +942,8 @@ fn test_eth_validate_valid_and_invalid_pubkey() { "coin": "MATIC", "urls": ["https://polygon-mainnet.g.alchemy.com/v2/9YYl6iMLmXXLoflMPHnMTC4Dcm2L2tFH"], "swap_contract_address": "0x9130b257d37a52e52f21054c4da3450c72f595ce", + "maker_swap_v2_contract": "0x9130b257d37a52e52f21054c4da3450c72f595ce", + "taker_swap_v2_contract": "0x9130b257d37a52e52f21054c4da3450c72f595ce", }); let priv_key = [ diff --git a/mm2src/coins/eth/eth_wasm_tests.rs b/mm2src/coins/eth/eth_wasm_tests.rs index a36e0ac45a..db6d2cce3f 100644 --- a/mm2src/coins/eth/eth_wasm_tests.rs +++ b/mm2src/coins/eth/eth_wasm_tests.rs @@ -40,7 +40,9 @@ async fn init_eth_coin_helper() -> Result<(MmArc, MmCoinEnum), String> { let req = json!({ "urls":ETH_SEPOLIA_NODES, - "swap_contract_address":ETH_SEPOLIA_SWAP_CONTRACT + "swap_contract_address":ETH_SEPOLIA_SWAP_CONTRACT, + "maker_swap_v2_contract":ETH_SEPOLIA_SWAP_CONTRACT, + "taker_swap_v2_contract":ETH_SEPOLIA_SWAP_CONTRACT, }); Ok((ctx.clone(), lp_coininit(&ctx, "ETH", &req).await?)) } diff --git a/mm2src/coins/eth/for_tests.rs b/mm2src/coins/eth/for_tests.rs index 9ea93188ea..d54390ae3c 100644 --- a/mm2src/coins/eth/for_tests.rs +++ b/mm2src/coins/eth/for_tests.rs @@ -58,6 +58,9 @@ pub(crate) fn eth_coin_from_keypair( priv_key_policy: key_pair.into(), derivation_method: Arc::new(DerivationMethod::SingleAddress(my_address)), swap_contract_address: Address::from_str(ETH_SEPOLIA_SWAP_CONTRACT).unwrap(), + maker_swap_v2_contract: Address::from_str(ETH_SEPOLIA_SWAP_CONTRACT).unwrap(), + taker_swap_v2_contract: Address::from_str(ETH_SEPOLIA_SWAP_CONTRACT).unwrap(), + nft_maker_swap_v2_contract: None, fallback_swap_contract, contract_supports_watchers: false, ticker, diff --git a/mm2src/coins/eth/maker_swap_v2_abi.json b/mm2src/coins/eth/maker_swap_v2_abi.json new file mode 100644 index 0000000000..ef34c01910 --- /dev/null +++ b/mm2src/coins/eth/maker_swap_v2_abi.json @@ -0,0 +1,311 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "MakerPaymentRefundedSecret", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "MakerPaymentRefundedTimelock", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "MakerPaymentSent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "MakerPaymentSpent", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "taker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecretHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecretHash", + "type": "bytes32" + }, + { + "internalType": "uint32", + "name": "paymentLockTime", + "type": "uint32" + } + ], + "name": "erc20MakerPayment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "taker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecretHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecretHash", + "type": "bytes32" + }, + { + "internalType": "uint32", + "name": "paymentLockTime", + "type": "uint32" + } + ], + "name": "ethMakerPayment", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "makerPayments", + "outputs": [ + { + "internalType": "bytes20", + "name": "paymentHash", + "type": "bytes20" + }, + { + "internalType": "uint32", + "name": "paymentLockTime", + "type": "uint32" + }, + { + "internalType": "enum EtomicSwapMakerV2.MakerPaymentState", + "name": "state", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "taker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecret", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecretHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "name": "refundMakerPaymentSecret", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "taker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecretHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecretHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "name": "refundMakerPaymentTimelock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecretHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecret", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "name": "spendMakerPayment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/mm2src/coins/eth/taker_swap_v2_abi.json b/mm2src/coins/eth/taker_swap_v2_abi.json new file mode 100644 index 0000000000..9e6b9df006 --- /dev/null +++ b/mm2src/coins/eth/taker_swap_v2_abi.json @@ -0,0 +1,443 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "feeAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "TakerPaymentApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "secret", + "type": "bytes32" + } + ], + "name": "TakerPaymentRefundedSecret", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "TakerPaymentRefundedTimelock", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "TakerPaymentSent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "secret", + "type": "bytes32" + } + ], + "name": "TakerPaymentSpent", + "type": "event" + }, + { + "inputs": [], + "name": "dexFeeAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dexFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecretHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecretHash", + "type": "bytes32" + }, + { + "internalType": "uint32", + "name": "preApproveLockTime", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "paymentLockTime", + "type": "uint32" + } + ], + "name": "erc20TakerPayment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "dexFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecretHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecretHash", + "type": "bytes32" + }, + { + "internalType": "uint32", + "name": "preApproveLockTime", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "paymentLockTime", + "type": "uint32" + } + ], + "name": "ethTakerPayment", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dexFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecret", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecretHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "name": "refundTakerPaymentSecret", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dexFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecretHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecretHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "name": "refundTakerPaymentTimelock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dexFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "taker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecretHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecret", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "name": "spendTakerPayment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dexFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "takerSecretHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "makerSecretHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "name": "takerPaymentApprove", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "takerPayments", + "outputs": [ + { + "internalType": "bytes20", + "name": "paymentHash", + "type": "bytes20" + }, + { + "internalType": "uint32", + "name": "preApproveLockTime", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "paymentLockTime", + "type": "uint32" + }, + { + "internalType": "enum EtomicSwapTakerV2.TakerPaymentState", + "name": "state", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 486f025c9e..d84b038390 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -181,6 +181,9 @@ pub struct EthActivationV2Request { #[serde(default)] pub rpc_mode: EthRpcMode, pub swap_contract_address: Address, + pub maker_swap_v2_contract: Address, + pub taker_swap_v2_contract: Address, + pub nft_maker_swap_v2_contract: Option
, pub fallback_swap_contract: Option
, #[serde(default)] pub contract_supports_watchers: bool, @@ -446,6 +449,9 @@ impl EthCoin { coin_type, sign_message_prefix: self.sign_message_prefix.clone(), swap_contract_address: self.swap_contract_address, + maker_swap_v2_contract: self.maker_swap_v2_contract, + taker_swap_v2_contract: self.taker_swap_v2_contract, + nft_maker_swap_v2_contract: self.nft_maker_swap_v2_contract, fallback_swap_contract: self.fallback_swap_contract, contract_supports_watchers: self.contract_supports_watchers, decimals, @@ -539,6 +545,9 @@ impl EthCoin { derivation_method: self.derivation_method.clone(), sign_message_prefix: self.sign_message_prefix.clone(), swap_contract_address: self.swap_contract_address, + maker_swap_v2_contract: self.maker_swap_v2_contract, + taker_swap_v2_contract: self.taker_swap_v2_contract, + nft_maker_swap_v2_contract: self.nft_maker_swap_v2_contract, fallback_swap_contract: self.fallback_swap_contract, contract_supports_watchers: self.contract_supports_watchers, web3_instances: AsyncMutex::new(web3_instances), @@ -696,6 +705,9 @@ pub async fn eth_coin_from_conf_and_request_v2( coin_type, sign_message_prefix, swap_contract_address: req.swap_contract_address, + maker_swap_v2_contract: req.maker_swap_v2_contract, + taker_swap_v2_contract: req.taker_swap_v2_contract, + nft_maker_swap_v2_contract: req.nft_maker_swap_v2_contract, fallback_swap_contract: req.fallback_swap_contract, contract_supports_watchers: req.contract_supports_watchers, decimals: ETH_DECIMALS, diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 2596e4eed9..ccef621f05 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -1,4 +1,4 @@ -pub use common::{block_on, now_ms, now_sec, wait_until_ms, wait_until_sec}; +pub use common::{block_on, now_ms, now_sec, wait_until_ms, wait_until_sec, DEX_FEE_ADDR_RAW_PUBKEY}; pub use mm2_number::MmNumber; use mm2_rpc::data::legacy::BalanceResponse; pub use mm2_test_helpers::for_tests::{check_my_swap_status, check_recent_swaps, enable_eth_coin, enable_native, @@ -42,19 +42,11 @@ use secp256k1::Secp256k1; pub use secp256k1::{PublicKey, SecretKey}; use serde_json::{self as json, Value as Json}; pub use std::env; -use std::path::PathBuf; -use std::process::Command; -use std::str::FromStr; -use std::sync::Mutex; pub use std::thread; -use std::time::Duration; -use testcontainers::clients::Cli; -use testcontainers::core::WaitFor; -use testcontainers::{Container, GenericImage, RunnableImage}; -use web3::transports::Http; -use web3::types::Address as EthAddress; -use web3::types::{BlockId, BlockNumber, TransactionRequest}; -use web3::Web3; +use std::{path::PathBuf, process::Command, str::FromStr, sync::Mutex, time::Duration}; +use testcontainers::{clients::Cli, core::WaitFor, Container, GenericImage, RunnableImage}; +use web3::types::{Address as EthAddress, BlockId, BlockNumber, TransactionRequest}; +use web3::{transports::Http, Web3}; lazy_static! { static ref MY_COIN_LOCK: Mutex<()> = Mutex::new(()); @@ -90,6 +82,10 @@ pub static mut GETH_ACCOUNT: H160Eth = H160Eth::zero(); pub static mut GETH_ERC20_CONTRACT: H160Eth = H160Eth::zero(); /// Swap contract address on Geth dev node pub static mut GETH_SWAP_CONTRACT: H160Eth = H160Eth::zero(); +/// Maker Swap V2 contract address on Geth dev node +pub static mut GETH_MAKER_SWAP_V2: H160Eth = H160Eth::zero(); +/// Taker Swap V2 contract address on Geth dev node +pub static mut GETH_TAKER_SWAP_V2: H160Eth = H160Eth::zero(); /// Swap contract (with watchers support) address on Geth dev node pub static mut GETH_WATCHERS_SWAP_CONTRACT: H160Eth = H160Eth::zero(); /// ERC721 token address on Geth dev node @@ -132,8 +128,12 @@ pub const WATCHERS_SWAP_CONTRACT_BYTES: &str = "608060405234801561000f575f80fd5b pub const ERC721_TEST_TOKEN_BYTES: &str = "608060405234801562000010575f80fd5b50604051620022ac380380620022ac8339818101604052810190620000369190620001ea565b8181815f9081620000489190620004a4565b5080600190816200005a9190620004a4565b505050505062000588565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c6826200007e565b810181811067ffffffffffffffff82111715620000e857620000e76200008e565b5b80604052505050565b5f620000fc62000065565b90506200010a8282620000bb565b919050565b5f67ffffffffffffffff8211156200012c576200012b6200008e565b5b62000137826200007e565b9050602081019050919050565b5f5b838110156200016357808201518184015260208101905062000146565b5f8484015250505050565b5f620001846200017e846200010f565b620000f1565b905082815260208101848484011115620001a357620001a26200007a565b5b620001b084828562000144565b509392505050565b5f82601f830112620001cf57620001ce62000076565b5b8151620001e18482602086016200016e565b91505092915050565b5f80604083850312156200020357620002026200006e565b5b5f83015167ffffffffffffffff81111562000223576200022262000072565b5b6200023185828601620001b8565b925050602083015167ffffffffffffffff81111562000255576200025462000072565b5b6200026385828601620001b8565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620002bc57607f821691505b602082108103620002d257620002d162000277565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002f9565b620003428683620002f9565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200038c6200038662000380846200035a565b62000363565b6200035a565b9050919050565b5f819050919050565b620003a7836200036c565b620003bf620003b68262000393565b84845462000305565b825550505050565b5f90565b620003d5620003c7565b620003e28184846200039c565b505050565b5b818110156200040957620003fd5f82620003cb565b600181019050620003e8565b5050565b601f82111562000458576200042281620002d8565b6200042d84620002ea565b810160208510156200043d578190505b620004556200044c85620002ea565b830182620003e7565b50505b505050565b5f82821c905092915050565b5f6200047a5f19846008026200045d565b1980831691505092915050565b5f62000494838362000469565b9150826002028217905092915050565b620004af826200026d565b67ffffffffffffffff811115620004cb57620004ca6200008e565b5b620004d78254620002a4565b620004e48282856200040d565b5f60209050601f8311600181146200051a575f841562000505578287015190505b62000511858262000487565b86555062000580565b601f1984166200052a86620002d8565b5f5b8281101562000553578489015182556001820191506020850194506020810190506200052c565b868310156200057357848901516200056f601f89168262000469565b8355505b6001600288020188555050505b505050505050565b611d1680620005965f395ff3fe608060405234801561000f575f80fd5b50600436106100e8575f3560e01c80636352211e1161008a578063a22cb46511610064578063a22cb46514610258578063b88d4fde14610274578063c87b56dd14610290578063e985e9c5146102c0576100e8565b80636352211e146101da57806370a082311461020a57806395d89b411461023a576100e8565b8063095ea7b3116100c6578063095ea7b31461016a57806323b872dd1461018657806340c10f19146101a257806342842e0e146101be576100e8565b806301ffc9a7146100ec57806306fdde031461011c578063081812fc1461013a575b5f80fd5b610106600480360381019061010191906115a7565b6102f0565b60405161011391906115ec565b60405180910390f35b6101246103d1565b604051610131919061168f565b60405180910390f35b610154600480360381019061014f91906116e2565b610460565b604051610161919061174c565b60405180910390f35b610184600480360381019061017f919061178f565b61047b565b005b6101a0600480360381019061019b91906117cd565b610491565b005b6101bc60048036038101906101b7919061178f565b610590565b005b6101d860048036038101906101d391906117cd565b61059e565b005b6101f460048036038101906101ef91906116e2565b6105bd565b604051610201919061174c565b60405180910390f35b610224600480360381019061021f919061181d565b6105ce565b6040516102319190611857565b60405180910390f35b610242610684565b60405161024f919061168f565b60405180910390f35b610272600480360381019061026d919061189a565b610714565b005b61028e60048036038101906102899190611a04565b61072a565b005b6102aa60048036038101906102a591906116e2565b610747565b6040516102b7919061168f565b60405180910390f35b6102da60048036038101906102d59190611a84565b6107ad565b6040516102e791906115ec565b60405180910390f35b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103ba57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103ca57506103c98261083b565b5b9050919050565b60605f80546103df90611aef565b80601f016020809104026020016040519081016040528092919081815260200182805461040b90611aef565b80156104565780601f1061042d57610100808354040283529160200191610456565b820191905f5260205f20905b81548152906001019060200180831161043957829003601f168201915b5050505050905090565b5f61046a826108a4565b506104748261092a565b9050919050565b61048d8282610488610963565b61096a565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610501575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016104f8919061174c565b60405180910390fd5b5f610514838361050f610963565b61097c565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461058a578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161058193929190611b1f565b60405180910390fd5b50505050565b61059a8282610b87565b5050565b6105b883838360405180602001604052805f81525061072a565b505050565b5f6105c7826108a4565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361063f575f6040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401610636919061174c565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b60606001805461069390611aef565b80601f01602080910402602001604051908101604052809291908181526020018280546106bf90611aef565b801561070a5780601f106106e15761010080835404028352916020019161070a565b820191905f5260205f20905b8154815290600101906020018083116106ed57829003601f168201915b5050505050905090565b61072661071f610963565b8383610c7a565b5050565b610735848484610491565b61074184848484610de3565b50505050565b6060610752826108a4565b505f61075c610f95565b90505f81511161077a5760405180602001604052805f8152506107a5565b8061078484610fab565b604051602001610795929190611b8e565b6040516020818303038152906040525b915050919050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f806108af83611075565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361092157826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016109189190611857565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b61097783838360016110ae565b505050565b5f8061098784611075565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146109c8576109c781848661126d565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a5357610a075f855f806110ae565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610ad257600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610bf7575f6040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610bee919061174c565b60405180910390fd5b5f610c0383835f61097c565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c75575f6040517f73c6ac6e000000000000000000000000000000000000000000000000000000008152600401610c6c919061174c565b60405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610cea57816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401610ce1919061174c565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610dd691906115ec565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b1115610f8f578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02610e26610963565b8685856040518563ffffffff1660e01b8152600401610e489493929190611c03565b6020604051808303815f875af1925050508015610e8357506040513d601f19601f82011682018060405250810190610e809190611c61565b60015b610f04573d805f8114610eb1576040519150601f19603f3d011682016040523d82523d5f602084013e610eb6565b606091505b505f815103610efc57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610ef3919061174c565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614610f8d57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610f84919061174c565b60405180910390fd5b505b50505050565b606060405180602001604052805f815250905090565b60605f6001610fb984611330565b0190505f8167ffffffffffffffff811115610fd757610fd66118e0565b5b6040519080825280601f01601f1916602001820160405280156110095781602001600182028036833780820191505090505b5090505f82602001820190505b60011561106a578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161105f5761105e611c8c565b5b0494505f8503611016575b819350505050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b80806110e657505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611218575f6110f5846108a4565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561115f57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611172575061117081846107ad565b155b156111b457826040517fa9fbf51f0000000000000000000000000000000000000000000000000000000081526004016111ab919061174c565b60405180910390fd5b811561121657838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b611278838383611481565b61132b575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036112ec57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016112e39190611857565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401611322929190611cb9565b60405180910390fd5b505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061138c577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161138257611381611c8c565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106113c9576d04ee2d6d415b85acef810000000083816113bf576113be611c8c565b5b0492506020810190505b662386f26fc1000083106113f857662386f26fc1000083816113ee576113ed611c8c565b5b0492506010810190505b6305f5e1008310611421576305f5e100838161141757611416611c8c565b5b0492506008810190505b612710831061144657612710838161143c5761143b611c8c565b5b0492506004810190505b60648310611469576064838161145f5761145e611c8c565b5b0492506002810190505b600a8310611478576001810190505b80915050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561153857508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806114f957506114f884846107ad565b5b8061153757508273ffffffffffffffffffffffffffffffffffffffff1661151f8361092a565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61158681611552565b8114611590575f80fd5b50565b5f813590506115a18161157d565b92915050565b5f602082840312156115bc576115bb61154a565b5b5f6115c984828501611593565b91505092915050565b5f8115159050919050565b6115e6816115d2565b82525050565b5f6020820190506115ff5f8301846115dd565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561163c578082015181840152602081019050611621565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61166182611605565b61166b818561160f565b935061167b81856020860161161f565b61168481611647565b840191505092915050565b5f6020820190508181035f8301526116a78184611657565b905092915050565b5f819050919050565b6116c1816116af565b81146116cb575f80fd5b50565b5f813590506116dc816116b8565b92915050565b5f602082840312156116f7576116f661154a565b5b5f611704848285016116ce565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6117368261170d565b9050919050565b6117468161172c565b82525050565b5f60208201905061175f5f83018461173d565b92915050565b61176e8161172c565b8114611778575f80fd5b50565b5f8135905061178981611765565b92915050565b5f80604083850312156117a5576117a461154a565b5b5f6117b28582860161177b565b92505060206117c3858286016116ce565b9150509250929050565b5f805f606084860312156117e4576117e361154a565b5b5f6117f18682870161177b565b93505060206118028682870161177b565b9250506040611813868287016116ce565b9150509250925092565b5f602082840312156118325761183161154a565b5b5f61183f8482850161177b565b91505092915050565b611851816116af565b82525050565b5f60208201905061186a5f830184611848565b92915050565b611879816115d2565b8114611883575f80fd5b50565b5f8135905061189481611870565b92915050565b5f80604083850312156118b0576118af61154a565b5b5f6118bd8582860161177b565b92505060206118ce85828601611886565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61191682611647565b810181811067ffffffffffffffff82111715611935576119346118e0565b5b80604052505050565b5f611947611541565b9050611953828261190d565b919050565b5f67ffffffffffffffff821115611972576119716118e0565b5b61197b82611647565b9050602081019050919050565b828183375f83830152505050565b5f6119a86119a384611958565b61193e565b9050828152602081018484840111156119c4576119c36118dc565b5b6119cf848285611988565b509392505050565b5f82601f8301126119eb576119ea6118d8565b5b81356119fb848260208601611996565b91505092915050565b5f805f8060808587031215611a1c57611a1b61154a565b5b5f611a298782880161177b565b9450506020611a3a8782880161177b565b9350506040611a4b878288016116ce565b925050606085013567ffffffffffffffff811115611a6c57611a6b61154e565b5b611a78878288016119d7565b91505092959194509250565b5f8060408385031215611a9a57611a9961154a565b5b5f611aa78582860161177b565b9250506020611ab88582860161177b565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611b0657607f821691505b602082108103611b1957611b18611ac2565b5b50919050565b5f606082019050611b325f83018661173d565b611b3f6020830185611848565b611b4c604083018461173d565b949350505050565b5f81905092915050565b5f611b6882611605565b611b728185611b54565b9350611b8281856020860161161f565b80840191505092915050565b5f611b998285611b5e565b9150611ba58284611b5e565b91508190509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f611bd582611bb1565b611bdf8185611bbb565b9350611bef81856020860161161f565b611bf881611647565b840191505092915050565b5f608082019050611c165f83018761173d565b611c23602083018661173d565b611c306040830185611848565b8181036060830152611c428184611bcb565b905095945050505050565b5f81519050611c5b8161157d565b92915050565b5f60208284031215611c7657611c7561154a565b5b5f611c8384828501611c4d565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f604082019050611ccc5f83018561173d565b611cd96020830184611848565b939250505056fea26469706673582212207439b47c2a9a1624955997732075917bbf1da26949d000c778f561eb5687576164736f6c63430008180033"; pub const ERC1155_TEST_TOKEN_BYTES: &str = "608060405234801562000010575f80fd5b50604051620024eb380380620024eb8339818101604052810190620000369190620001ea565b8062000048816200005060201b60201c565b505062000554565b806002908162000061919062000470565b5050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c6826200007e565b810181811067ffffffffffffffff82111715620000e857620000e76200008e565b5b80604052505050565b5f620000fc62000065565b90506200010a8282620000bb565b919050565b5f67ffffffffffffffff8211156200012c576200012b6200008e565b5b62000137826200007e565b9050602081019050919050565b5f5b838110156200016357808201518184015260208101905062000146565b5f8484015250505050565b5f620001846200017e846200010f565b620000f1565b905082815260208101848484011115620001a357620001a26200007a565b5b620001b084828562000144565b509392505050565b5f82601f830112620001cf57620001ce62000076565b5b8151620001e18482602086016200016e565b91505092915050565b5f602082840312156200020257620002016200006e565b5b5f82015167ffffffffffffffff81111562000222576200022162000072565b5b6200023084828501620001b8565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200028857607f821691505b6020821081036200029e576200029d62000243565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002c5565b6200030e8683620002c5565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f62000358620003526200034c8462000326565b6200032f565b62000326565b9050919050565b5f819050919050565b620003738362000338565b6200038b62000382826200035f565b848454620002d1565b825550505050565b5f90565b620003a162000393565b620003ae81848462000368565b505050565b5b81811015620003d557620003c95f8262000397565b600181019050620003b4565b5050565b601f8211156200042457620003ee81620002a4565b620003f984620002b6565b8101602085101562000409578190505b620004216200041885620002b6565b830182620003b3565b50505b505050565b5f82821c905092915050565b5f620004465f198460080262000429565b1980831691505092915050565b5f62000460838362000435565b9150826002028217905092915050565b6200047b8262000239565b67ffffffffffffffff8111156200049757620004966200008e565b5b620004a3825462000270565b620004b0828285620003d9565b5f60209050601f831160018114620004e6575f8415620004d1578287015190505b620004dd858262000453565b8655506200054c565b601f198416620004f686620002a4565b5f5b828110156200051f57848901518255600182019150602085019450602081019050620004f8565b868310156200053f57848901516200053b601f89168262000435565b8355505b6001600288020188555050505b505050505050565b611f8980620005625f395ff3fe608060405234801561000f575f80fd5b5060043610610090575f3560e01c80634e1273f4116100645780634e1273f414610140578063731133e914610170578063a22cb4651461018c578063e985e9c5146101a8578063f242432a146101d857610090565b8062fdd58e1461009457806301ffc9a7146100c45780630e89341c146100f45780632eb2c2d614610124575b5f80fd5b6100ae60048036038101906100a991906113bd565b6101f4565b6040516100bb919061140a565b60405180910390f35b6100de60048036038101906100d99190611478565b610249565b6040516100eb91906114bd565b60405180910390f35b61010e600480360381019061010991906114d6565b61032a565b60405161011b919061158b565b60405180910390f35b61013e6004803603810190610139919061179b565b6103bc565b005b61015a60048036038101906101559190611926565b610463565b6040516101679190611a53565b60405180910390f35b61018a60048036038101906101859190611a73565b61056a565b005b6101a660048036038101906101a19190611b1d565b61057c565b005b6101c260048036038101906101bd9190611b5b565b610592565b6040516101cf91906114bd565b60405180910390f35b6101f260048036038101906101ed9190611b99565b610620565b005b5f805f8381526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f7fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061031357507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103235750610322826106c7565b5b9050919050565b60606002805461033990611c59565b80601f016020809104026020016040519081016040528092919081815260200182805461036590611c59565b80156103b05780601f10610387576101008083540402835291602001916103b0565b820191905f5260205f20905b81548152906001019060200180831161039357829003601f168201915b50505050509050919050565b5f6103c5610730565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561040a57506104088682610592565b155b1561044e5780866040517fe237d922000000000000000000000000000000000000000000000000000000008152600401610445929190611c98565b60405180910390fd5b61045b8686868686610737565b505050505050565b606081518351146104af57815183516040517f5b0599910000000000000000000000000000000000000000000000000000000081526004016104a6929190611cbf565b60405180910390fd5b5f835167ffffffffffffffff8111156104cb576104ca6115af565b5b6040519080825280602002602001820160405280156104f95781602001602082028036833780820191505090505b5090505f5b845181101561055f5761053561051d828761082b90919063ffffffff16565b610530838761083e90919063ffffffff16565b6101f4565b82828151811061054857610547611ce6565b5b6020026020010181815250508060010190506104fe565b508091505092915050565b61057684848484610851565b50505050565b61058e610587610730565b83836108e6565b5050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f610629610730565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561066e575061066c8682610592565b155b156106b25780866040517fe237d9220000000000000000000000000000000000000000000000000000000081526004016106a9929190611c98565b60405180910390fd5b6106bf8686868686610a4f565b505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036107a7575f6040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161079e9190611d13565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610817575f6040517f01a8351400000000000000000000000000000000000000000000000000000000815260040161080e9190611d13565b60405180910390fd5b6108248585858585610b55565b5050505050565b5f60208202602084010151905092915050565b5f60208202602084010151905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036108c1575f6040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016108b89190611d13565b60405180910390fd5b5f806108cd8585610c01565b915091506108de5f87848487610b55565b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610956575f6040517fced3e10000000000000000000000000000000000000000000000000000000000815260040161094d9190611d13565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610a4291906114bd565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610abf575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401610ab69190611d13565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610b2f575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401610b269190611d13565b60405180910390fd5b5f80610b3b8585610c01565b91509150610b4c8787848487610b55565b50505050505050565b610b6185858585610c31565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610bfa575f610b9d610730565b90506001845103610be9575f610bbc5f8661083e90919063ffffffff16565b90505f610bd25f8661083e90919063ffffffff16565b9050610be2838989858589610fc1565b5050610bf8565b610bf7818787878787611170565b5b505b5050505050565b60608060405191506001825283602083015260408201905060018152826020820152604081016040529250929050565b8051825114610c7b57815181516040517f5b059991000000000000000000000000000000000000000000000000000000008152600401610c72929190611cbf565b60405180910390fd5b5f610c84610730565b90505f5b8351811015610e80575f610ca5828661083e90919063ffffffff16565b90505f610cbb838661083e90919063ffffffff16565b90505f73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614610dde575f805f8481526020019081526020015f205f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015610d8a57888183856040517f03dee4c5000000000000000000000000000000000000000000000000000000008152600401610d819493929190611d2c565b60405180910390fd5b8181035f808581526020019081526020015f205f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610e7357805f808481526020019081526020015f205f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610e6b9190611d9c565b925050819055505b5050806001019050610c88565b506001835103610f3b575f610e9e5f8561083e90919063ffffffff16565b90505f610eb45f8561083e90919063ffffffff16565b90508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051610f2c929190611cbf565b60405180910390a45050610fba565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051610fb1929190611dcf565b60405180910390a45b5050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115611168578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b8152600401611021959493929190611e56565b6020604051808303815f875af192505050801561105c57506040513d601f19601f820116820180604052508101906110599190611ec2565b60015b6110dd573d805f811461108a576040519150601f19603f3d011682016040523d82523d5f602084013e61108f565b606091505b505f8151036110d557846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016110cc9190611d13565b60405180910390fd5b805181602001fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461116657846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161115d9190611d13565b60405180910390fd5b505b505050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115611317578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b81526004016111d0959493929190611eed565b6020604051808303815f875af192505050801561120b57506040513d601f19601f820116820180604052508101906112089190611ec2565b60015b61128c573d805f8114611239576040519150601f19603f3d011682016040523d82523d5f602084013e61123e565b606091505b505f81510361128457846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161127b9190611d13565b60405180910390fd5b805181602001fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461131557846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161130c9190611d13565b60405180910390fd5b505b505050505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61135982611330565b9050919050565b6113698161134f565b8114611373575f80fd5b50565b5f8135905061138481611360565b92915050565b5f819050919050565b61139c8161138a565b81146113a6575f80fd5b50565b5f813590506113b781611393565b92915050565b5f80604083850312156113d3576113d2611328565b5b5f6113e085828601611376565b92505060206113f1858286016113a9565b9150509250929050565b6114048161138a565b82525050565b5f60208201905061141d5f8301846113fb565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61145781611423565b8114611461575f80fd5b50565b5f813590506114728161144e565b92915050565b5f6020828403121561148d5761148c611328565b5b5f61149a84828501611464565b91505092915050565b5f8115159050919050565b6114b7816114a3565b82525050565b5f6020820190506114d05f8301846114ae565b92915050565b5f602082840312156114eb576114ea611328565b5b5f6114f8848285016113a9565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561153857808201518184015260208101905061151d565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61155d82611501565b611567818561150b565b935061157781856020860161151b565b61158081611543565b840191505092915050565b5f6020820190508181035f8301526115a38184611553565b905092915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6115e582611543565b810181811067ffffffffffffffff82111715611604576116036115af565b5b80604052505050565b5f61161661131f565b905061162282826115dc565b919050565b5f67ffffffffffffffff821115611641576116406115af565b5b602082029050602081019050919050565b5f80fd5b5f61166861166384611627565b61160d565b9050808382526020820190506020840283018581111561168b5761168a611652565b5b835b818110156116b457806116a088826113a9565b84526020840193505060208101905061168d565b5050509392505050565b5f82601f8301126116d2576116d16115ab565b5b81356116e2848260208601611656565b91505092915050565b5f80fd5b5f67ffffffffffffffff821115611709576117086115af565b5b61171282611543565b9050602081019050919050565b828183375f83830152505050565b5f61173f61173a846116ef565b61160d565b90508281526020810184848401111561175b5761175a6116eb565b5b61176684828561171f565b509392505050565b5f82601f830112611782576117816115ab565b5b813561179284826020860161172d565b91505092915050565b5f805f805f60a086880312156117b4576117b3611328565b5b5f6117c188828901611376565b95505060206117d288828901611376565b945050604086013567ffffffffffffffff8111156117f3576117f261132c565b5b6117ff888289016116be565b935050606086013567ffffffffffffffff8111156118205761181f61132c565b5b61182c888289016116be565b925050608086013567ffffffffffffffff81111561184d5761184c61132c565b5b6118598882890161176e565b9150509295509295909350565b5f67ffffffffffffffff8211156118805761187f6115af565b5b602082029050602081019050919050565b5f6118a361189e84611866565b61160d565b905080838252602082019050602084028301858111156118c6576118c5611652565b5b835b818110156118ef57806118db8882611376565b8452602084019350506020810190506118c8565b5050509392505050565b5f82601f83011261190d5761190c6115ab565b5b813561191d848260208601611891565b91505092915050565b5f806040838503121561193c5761193b611328565b5b5f83013567ffffffffffffffff8111156119595761195861132c565b5b611965858286016118f9565b925050602083013567ffffffffffffffff8111156119865761198561132c565b5b611992858286016116be565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6119ce8161138a565b82525050565b5f6119df83836119c5565b60208301905092915050565b5f602082019050919050565b5f611a018261199c565b611a0b81856119a6565b9350611a16836119b6565b805f5b83811015611a46578151611a2d88826119d4565b9750611a38836119eb565b925050600181019050611a19565b5085935050505092915050565b5f6020820190508181035f830152611a6b81846119f7565b905092915050565b5f805f8060808587031215611a8b57611a8a611328565b5b5f611a9887828801611376565b9450506020611aa9878288016113a9565b9350506040611aba878288016113a9565b925050606085013567ffffffffffffffff811115611adb57611ada61132c565b5b611ae78782880161176e565b91505092959194509250565b611afc816114a3565b8114611b06575f80fd5b50565b5f81359050611b1781611af3565b92915050565b5f8060408385031215611b3357611b32611328565b5b5f611b4085828601611376565b9250506020611b5185828601611b09565b9150509250929050565b5f8060408385031215611b7157611b70611328565b5b5f611b7e85828601611376565b9250506020611b8f85828601611376565b9150509250929050565b5f805f805f60a08688031215611bb257611bb1611328565b5b5f611bbf88828901611376565b9550506020611bd088828901611376565b9450506040611be1888289016113a9565b9350506060611bf2888289016113a9565b925050608086013567ffffffffffffffff811115611c1357611c1261132c565b5b611c1f8882890161176e565b9150509295509295909350565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611c7057607f821691505b602082108103611c8357611c82611c2c565b5b50919050565b611c928161134f565b82525050565b5f604082019050611cab5f830185611c89565b611cb86020830184611c89565b9392505050565b5f604082019050611cd25f8301856113fb565b611cdf60208301846113fb565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f602082019050611d265f830184611c89565b92915050565b5f608082019050611d3f5f830187611c89565b611d4c60208301866113fb565b611d5960408301856113fb565b611d6660608301846113fb565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611da68261138a565b9150611db18361138a565b9250828201905080821115611dc957611dc8611d6f565b5b92915050565b5f6040820190508181035f830152611de781856119f7565b90508181036020830152611dfb81846119f7565b90509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f611e2882611e04565b611e328185611e0e565b9350611e4281856020860161151b565b611e4b81611543565b840191505092915050565b5f60a082019050611e695f830188611c89565b611e766020830187611c89565b611e8360408301866113fb565b611e9060608301856113fb565b8181036080830152611ea28184611e1e565b90509695505050505050565b5f81519050611ebc8161144e565b92915050565b5f60208284031215611ed757611ed6611328565b5b5f611ee484828501611eae565b91505092915050565b5f60a082019050611f005f830188611c89565b611f0d6020830187611c89565b8181036040830152611f1f81866119f7565b90508181036060830152611f3381856119f7565b90508181036080830152611f478184611e1e565b9050969550505050505056fea26469706673582212203835581c6344b12728c44fa4d9e912cd60e64012c1b772bb703d1c36825c16fd64736f6c63430008180033"; pub const NFT_SWAP_CONTRACT_BYTES: &str = "60a060405234801562000010575f80fd5b50604051620055a2380380620055a2833981810160405281019062000036919062000147565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200009e90620001fb565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506200021b565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200011182620000e6565b9050919050565b620001238162000105565b81146200012e575f80fd5b50565b5f81519050620001418162000118565b92915050565b5f602082840312156200015f576200015e620000e2565b5b5f6200016e8482850162000131565b91505092915050565b5f82825260208201905092915050565b7f66656541646472657373206d757374206e6f74206265207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f620001e360238362000177565b9150620001f08262000187565b604082019050919050565b5f6020820190508181035f8301526200021481620001d5565b9050919050565b608051615360620002425f395f8181612aef01528181612b8a0152612f4801526153605ff3fe608060405260043610610113575f3560e01c80639b4603f21161009f578063cc90c19911610063578063cc90c1991461038e578063d6a71eb4146103b6578063e06cf966146103de578063efccb9eb14610408578063f23a6e611461044657610113565b80639b4603f2146102be578063b27e46fb146102da578063bc197c8114610302578063c8d9009b1461033e578063c92cd12d1461036657610113565b8063150b7a02116100e6578063150b7a02146101cb5780633e6af5f21461020757806346b95ac71461022f57806365e266171461026e5780636e6bf6d21461029657610113565b806301ffc9a71461011757806305ec158d146101535780630f235fce1461017b578063146e5b24146101a3575b5f80fd5b348015610122575f80fd5b5061013d6004803603810190610138919061386f565b610482565b60405161014a91906138b4565b60405180910390f35b34801561015e575f80fd5b506101796004803603810190610174919061398d565b610563565b005b348015610186575f80fd5b506101a1600480360381019061019c9190613a2a565b610823565b005b3480156101ae575f80fd5b506101c960048036038101906101c49190613ab3565b610add565b005b3480156101d6575f80fd5b506101f160048036038101906101ec9190613bb1565b610cc3565b6040516101fe9190613c44565b60405180910390f35b348015610212575f80fd5b5061022d60048036038101906102289190613ab3565b611112565b005b34801561023a575f80fd5b5061025560048036038101906102509190613c5d565b611423565b6040516102659493929190613d53565b60405180910390f35b348015610279575f80fd5b50610294600480360381019061028f9190613ab3565b611485565b005b3480156102a1575f80fd5b506102bc60048036038101906102b79190613a2a565b6118e9565b005b6102d860048036038101906102d39190613dc0565b611ba4565b005b3480156102e5575f80fd5b5061030060048036038101906102fb919061398d565b611eda565b005b34801561030d575f80fd5b5061032860048036038101906103239190613eb2565b612199565b6040516103359190613c44565b60405180910390f35b348015610349575f80fd5b50610364600480360381019061035f9190613a2a565b6121d5565b005b348015610371575f80fd5b5061038c6004803603810190610387919061398d565b6124fe565b005b348015610399575f80fd5b506103b460048036038101906103af9190613ab3565b61282c565b005b3480156103c1575f80fd5b506103dc60048036038101906103d79190613f89565b612bdc565b005b3480156103e9575f80fd5b506103f2612f46565b6040516103ff919061405c565b60405180910390f35b348015610413575f80fd5b5061042e60048036038101906104299190613c5d565b612f6a565b60405161043d939291906140bb565b60405180910390f35b348015610451575f80fd5b5061046c600480360381019061046791906140f0565b612fb6565b6040516104799190613c44565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061054c57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061055c575061055b8261344a565b5b9050919050565b6001600381111561057757610576613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff1660038111156105a9576105a8613ce0565b5b146105e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e090614206565b60405180910390fd5b5f600387336002896040516020016106019190614244565b60405160208183030381529060405260405161061d91906142ca565b602060405180830381855afa158015610638573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065b91906142f4565b888888886040516020016106759796959493929190614384565b60405160208183030381529060405260405161069191906142ca565b602060405180830381855afa1580156106ac573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610736576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072d9061444e565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561076c5761076b613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd73886040516107a0919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016107eb94939291906144d6565b5f604051808303815f87803b158015610802575f80fd5b505af1158015610814573d5f803e3d5ffd5b50505050505050505050505050565b6001600381111561083757610836613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561086957610868613ce0565b5b146108a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a090614206565b60405180910390fd5b5f60038633878787876040516020016108c79695949392919061452c565b6040516020818303038152906040526040516108e391906142ca565b602060405180830381855afa1580156108fe573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097f9061444e565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156109f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ea9061460b565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610a2957610a28613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907287604051610a5d919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610aa693929190614629565b5f604051808303815f87803b158015610abd575f80fd5b505af1158015610acf573d5f803e3d5ffd5b505050505050505050505050565b60016004811115610af157610af0613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115610b2457610b23613ce0565b5b14610b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5b90614206565b60405180910390fd5b5f600387878733888888604051602001610b84979695949392919061465e565b604051602081830303815290604052604051610ba091906142ca565b602060405180830381855afa158015610bbb573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610c46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3d9061444e565b60405180910390fd5b600260015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610c7d57610c7c613ce0565b5b02179055507f9c45e43e2ef051f70491ffd5221bf02ab37e1324128714ef9610df5f24fc9fb588604051610cb1919061447b565b60405180910390a15050505050505050565b5f808383810190610cd49190614807565b90505f6003811115610ce957610ce8613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff166003811115610d1e57610d1d613ce0565b5b14610d5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d55906148a2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603610dd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc79061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610e42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3990614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610eb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eab90614a00565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610f22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1990614a68565b60405180910390fd5b610f2f81602001516134b3565b15610f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6690614ad0565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610f9d9695949392919061452c565b604051602081830303815290604052604051610fb991906142ca565b602060405180830381855afa158015610fd4573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561102457611023613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156110bb576110ba613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f01516040516110f5919061447b565b60405180910390a163150b7a0260e01b9250505095945050505050565b6001600481111561112657611125613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561115957611158613ce0565b5b14611199576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119090614206565b60405180910390fd5b5f6003878787336002896040516020016111b39190614244565b6040516020818303038152906040526040516111cf91906142ca565b602060405180830381855afa1580156111ea573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061120d91906142f4565b8888604051602001611225979695949392919061465e565b60405160208183030381529060405260405161124191906142ca565b602060405180830381855afa15801561125c573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146112e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112de9061444e565b60405180910390fd5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff0219169083600481111561131e5761131d613ce0565b5b02179055507f45169a52eef651b20a81474b50b8a5d83225225fcd097ef3cf7952d9ab304f278885604051611354929190614aee565b60405180910390a15f86886113699190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113e7573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156113e1573d5f803e3d5ffd5b50611418565b5f83905061141633838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b6001602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900463ffffffff1690805f01601c9054906101000a900460ff16905084565b6001600481111561149957611498613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff1660048111156114cc576114cb613ce0565b5b148061151c5750600260048111156114e7576114e6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561151a57611519613ce0565b5b145b61155b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155290614be5565b60405180910390fd5b5f60038787873388888860405160200161157b979695949392919061465e565b60405160208183030381529060405260405161159791906142ca565b602060405180830381855afa1580156115b2573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461163d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116349061444e565b60405180910390fd5b6002600481111561165157611650613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561168457611683613ce0565b5b036116f65760015f8981526020019081526020015f205f0160189054906101000a900463ffffffff1663ffffffff164210156116f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ec9061460b565b60405180910390fd5b5b6001600481111561170a57611709613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561173d5761173c613ce0565b5b036117af5760015f8981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156117ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a590614c73565b60405180910390fd5b5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156117e6576117e5613ce0565b5b02179055507fbdd7a4be6d82798a500b59077706b12d3f45acf5504828919f92501307b2b9538860405161181a919061447b565b60405180910390a15f868861182f9190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118ad573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156118a7573d5f803e3d5ffd5b506118de565b5f8390506118dc33838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b600160038111156118fd576118fc613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561192f5761192e613ce0565b5b1461196f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196690614206565b60405180910390fd5b5f600386336002886040516020016119879190614244565b6040516020818303038152906040526040516119a391906142ca565b602060405180830381855afa1580156119be573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906119e191906142f4565b8787876040516020016119f99695949392919061452c565b604051602081830303815290604052604051611a1591906142ca565b602060405180830381855afa158015611a30573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611aba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab19061444e565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115611af057611aef613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051611b24919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401611b6d93929190614629565b5f604051808303815f87803b158015611b84575f80fd5b505af1158015611b96573d5f803e3d5ffd5b505050505050505050505050565b5f6004811115611bb757611bb6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115611bea57611be9613ce0565b5b14611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2190614d01565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611c98576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8f90614d8f565b60405180910390fd5b5f3411611cda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd190614e1d565b60405180910390fd5b853411611d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1390614eab565b60405180910390fd5b5f60038734611d2b9190614ec9565b88883389895f604051602001611d47979695949392919061465e565b604051602081830303815290604052604051611d6391906142ca565b602060405180830381855afa158015611d7e573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115611dd657611dd5613ce0565b5b81525060015f8a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115611e9157611e90613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd93588604051611ec8919061447b565b60405180910390a15050505050505050565b60016003811115611eee57611eed613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115611f2057611f1f613ce0565b5b14611f60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5790614206565b60405180910390fd5b5f600387338888888888604051602001611f809796959493929190614384565b604051602081830303815290604052604051611f9c91906142ca565b602060405180830381855afa158015611fb7573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612041576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120389061444e565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156120ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a39061460b565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156120e2576120e1613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907288604051612116919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161216194939291906144d6565b5f604051808303815f87803b158015612178575f80fd5b505af115801561218a573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121cc90614f46565b60405180910390fd5b600160038111156121e9576121e8613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561221b5761221a613ce0565b5b1461225b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161225290614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c090614fae565b60405180910390fd5b5f60033387876002886040516020016122e29190614244565b6040516020818303038152906040526040516122fe91906142ca565b602060405180830381855afa158015612319573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061233c91906142f4565b87876040516020016123539695949392919061452c565b60405160208183030381529060405260405161236f91906142ca565b602060405180830381855afa15801561238a573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612414576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240b9061444e565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561244a57612449613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161247e919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016124c793929190614629565b5f604051808303815f87803b1580156124de575f80fd5b505af11580156124f0573d5f803e3d5ffd5b505050505050505050505050565b6001600381111561251257612511613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561254457612543613ce0565b5b14612584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257b90614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146125f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125e990614fae565b60405180910390fd5b5f600333888860028960405160200161260b9190614244565b60405160208183030381529060405260405161262791906142ca565b602060405180830381855afa158015612642573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061266591906142f4565b88888860405160200161267e9796959493929190614384565b60405160208183030381529060405260405161269a91906142ca565b602060405180830381855afa1580156126b5573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461273f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127369061444e565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561277557612774613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0886040516127a9919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016127f494939291906144d6565b5f604051808303815f87803b15801561280b575f80fd5b505af115801561281d573d5f803e3d5ffd5b50505050505050505050505050565b600260048111156128405761283f613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561287357612872613ce0565b5b146128b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128aa9061503c565b60405180910390fd5b5f600387873388886002896040516020016128ce9190614244565b6040516020818303038152906040526040516128ea91906142ca565b602060405180830381855afa158015612905573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061292891906142f4565b8860405160200161293f979695949392919061465e565b60405160208183030381529060405260405161295b91906142ca565b602060405180830381855afa158015612976573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612a01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129f89061444e565b60405180910390fd5b600360015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115612a3857612a37613ce0565b5b02179055507f0d0da0df275f85bed3a5fe7ae79f3559341a3f9ccd8e010133438135bda00a878884604051612a6e929190614aee565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612b56573373ffffffffffffffffffffffffffffffffffffffff166108fc8890811502906040515f60405180830381858888f19350505050158015612aec573d5f803e3d5ffd5b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f19350505050158015612b50573d5f803e3d5ffd5b50612bd2565b5f829050612b8533898373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b612bd07f0000000000000000000000000000000000000000000000000000000000000000888373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b5050505050505050565b5f6004811115612bef57612bee613ce0565b5b60015f8b81526020019081526020015f205f01601c9054906101000a900460ff166004811115612c2257612c21613ce0565b5b14612c62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c59906150ca565b60405180910390fd5b5f8811612ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c9b90615132565b60405180910390fd5b5f8711612ce6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cdd9061519a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612d54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d4b90614d8f565b60405180910390fd5b5f60038989883389898d604051602001612d74979695949392919061465e565b604051602081830303815290604052604051612d9091906142ca565b602060405180830381855afa158015612dab573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115612e0357612e02613ce0565b5b81525060015f8c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115612ebe57612ebd613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358a604051612ef5919061447b565b60405180910390a15f879050612f3933308b8d612f129190614b42565b8473ffffffffffffffffffffffffffffffffffffffff16613543909392919063ffffffff16565b5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f808383810190612fc79190614807565b90505f6003811115612fdc57612fdb613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff16600381111561301157613010613ce0565b5b14613051576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161304890615228565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff16036130c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130ba9061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161312c90614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146131a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161319e90614a00565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614613215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161320c90614a68565b60405180910390fd5b5f8511613257576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161324e90615290565b60405180910390fd5b61326481602001516134b3565b156132a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161329b90614ad0565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c6040516020016132d49796959493929190614384565b6040516020818303038152906040526040516132f091906142ca565b602060405180830381855afa15801561330b573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561335b5761335a613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156133f2576133f1613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f015160405161342c919061447b565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b61353e838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85856040516024016134f79291906152ae565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b505050565b6135bf848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161357893929190614629565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b50505050565b5f6135ef828473ffffffffffffffffffffffffffffffffffffffff1661365a90919063ffffffff16565b90505f81511415801561361357508080602001905181019061361191906152ff565b155b1561365557826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161364c919061405c565b60405180910390fd5b505050565b606061366783835f61366f565b905092915050565b6060814710156136b657306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016136ad919061405c565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516136de91906142ca565b5f6040518083038185875af1925050503d805f8114613718576040519150601f19603f3d011682016040523d82523d5f602084013e61371d565b606091505b509150915061372d868383613738565b925050509392505050565b60608261374d57613748826137c5565b6137bd565b5f825114801561377357505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156137b557836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016137ac919061405c565b60405180910390fd5b8190506137be565b5b9392505050565b5f815111156137d75780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61384e8161381a565b8114613858575f80fd5b50565b5f8135905061386981613845565b92915050565b5f6020828403121561388457613883613812565b5b5f6138918482850161385b565b91505092915050565b5f8115159050919050565b6138ae8161389a565b82525050565b5f6020820190506138c75f8301846138a5565b92915050565b5f819050919050565b6138df816138cd565b81146138e9575f80fd5b50565b5f813590506138fa816138d6565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61392982613900565b9050919050565b6139398161391f565b8114613943575f80fd5b50565b5f8135905061395481613930565b92915050565b5f819050919050565b61396c8161395a565b8114613976575f80fd5b50565b5f8135905061398781613963565b92915050565b5f805f805f805f60e0888a0312156139a8576139a7613812565b5b5f6139b58a828b016138ec565b97505060206139c68a828b01613946565b96505060406139d78a828b016138ec565b95505060606139e88a828b016138ec565b94505060806139f98a828b01613946565b93505060a0613a0a8a828b01613979565b92505060c0613a1b8a828b01613979565b91505092959891949750929550565b5f805f805f8060c08789031215613a4457613a43613812565b5b5f613a5189828a016138ec565b9650506020613a6289828a01613946565b9550506040613a7389828a016138ec565b9450506060613a8489828a016138ec565b9350506080613a9589828a01613946565b92505060a0613aa689828a01613979565b9150509295509295509295565b5f805f805f805f60e0888a031215613ace57613acd613812565b5b5f613adb8a828b016138ec565b9750506020613aec8a828b01613979565b9650506040613afd8a828b01613979565b9550506060613b0e8a828b01613946565b9450506080613b1f8a828b016138ec565b93505060a0613b308a828b016138ec565b92505060c0613b418a828b01613946565b91505092959891949750929550565b5f80fd5b5f80fd5b5f80fd5b5f8083601f840112613b7157613b70613b50565b5b8235905067ffffffffffffffff811115613b8e57613b8d613b54565b5b602083019150836001820283011115613baa57613ba9613b58565b5b9250929050565b5f805f805f60808688031215613bca57613bc9613812565b5b5f613bd788828901613946565b9550506020613be888828901613946565b9450506040613bf988828901613979565b935050606086013567ffffffffffffffff811115613c1a57613c19613816565b5b613c2688828901613b5c565b92509250509295509295909350565b613c3e8161381a565b82525050565b5f602082019050613c575f830184613c35565b92915050565b5f60208284031215613c7257613c71613812565b5b5f613c7f848285016138ec565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b613cbc81613c88565b82525050565b5f63ffffffff82169050919050565b613cda81613cc2565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60058110613d1e57613d1d613ce0565b5b50565b5f819050613d2e82613d0d565b919050565b5f613d3d82613d21565b9050919050565b613d4d81613d33565b82525050565b5f608082019050613d665f830187613cb3565b613d736020830186613cd1565b613d806040830185613cd1565b613d8d6060830184613d44565b95945050505050565b613d9f81613cc2565b8114613da9575f80fd5b50565b5f81359050613dba81613d96565b92915050565b5f805f805f805f60e0888a031215613ddb57613dda613812565b5b5f613de88a828b016138ec565b9750506020613df98a828b01613979565b9650506040613e0a8a828b01613946565b9550506060613e1b8a828b016138ec565b9450506080613e2c8a828b016138ec565b93505060a0613e3d8a828b01613dac565b92505060c0613e4e8a828b01613dac565b91505092959891949750929550565b5f8083601f840112613e7257613e71613b50565b5b8235905067ffffffffffffffff811115613e8f57613e8e613b54565b5b602083019150836020820283011115613eab57613eaa613b58565b5b9250929050565b5f805f805f805f8060a0898b031215613ece57613ecd613812565b5b5f613edb8b828c01613946565b9850506020613eec8b828c01613946565b975050604089013567ffffffffffffffff811115613f0d57613f0c613816565b5b613f198b828c01613e5d565b9650965050606089013567ffffffffffffffff811115613f3c57613f3b613816565b5b613f488b828c01613e5d565b9450945050608089013567ffffffffffffffff811115613f6b57613f6a613816565b5b613f778b828c01613b5c565b92509250509295985092959890939650565b5f805f805f805f805f6101208a8c031215613fa757613fa6613812565b5b5f613fb48c828d016138ec565b9950506020613fc58c828d01613979565b9850506040613fd68c828d01613979565b9750506060613fe78c828d01613946565b9650506080613ff88c828d01613946565b95505060a06140098c828d016138ec565b94505060c061401a8c828d016138ec565b93505060e061402b8c828d01613dac565b92505061010061403d8c828d01613dac565b9150509295985092959850929598565b6140568161391f565b82525050565b5f60208201905061406f5f83018461404d565b92915050565b6004811061408657614085613ce0565b5b50565b5f81905061409682614075565b919050565b5f6140a582614089565b9050919050565b6140b58161409b565b82525050565b5f6060820190506140ce5f830186613cb3565b6140db6020830185613cd1565b6140e860408301846140ac565b949350505050565b5f805f805f8060a0878903121561410a57614109613812565b5b5f61411789828a01613946565b965050602061412889828a01613946565b955050604061413989828a01613979565b945050606061414a89828a01613979565b935050608087013567ffffffffffffffff81111561416b5761416a613816565b5b61417789828a01613b5c565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f6141f0602a83614186565b91506141fb82614196565b604082019050919050565b5f6020820190508181035f83015261421d816141e4565b9050919050565b5f819050919050565b61423e614239826138cd565b614224565b82525050565b5f61424f828461422d565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b5f5b8381101561428f578082015181840152602081019050614274565b5f8484015250505050565b5f6142a48261425e565b6142ae8185614268565b93506142be818560208601614272565b80840191505092915050565b5f6142d5828461429a565b915081905092915050565b5f815190506142ee816138d6565b92915050565b5f6020828403121561430957614308613812565b5b5f614316848285016142e0565b91505092915050565b5f8160601b9050919050565b5f6143358261431f565b9050919050565b5f6143468261432b565b9050919050565b61435e6143598261391f565b61433c565b82525050565b5f819050919050565b61437e6143798261395a565b614364565b82525050565b5f61438f828a61434d565b60148201915061439f828961434d565b6014820191506143af828861422d565b6020820191506143bf828761422d565b6020820191506143cf828661434d565b6014820191506143df828561436d565b6020820191506143ef828461436d565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f614438601383614186565b915061444382614404565b602082019050919050565b5f6020820190508181035f8301526144658161442c565b9050919050565b614475816138cd565b82525050565b5f60208201905061448e5f83018461446c565b92915050565b61449d8161395a565b82525050565b5f82825260208201905092915050565b50565b5f6144c15f836144a3565b91506144cc826144b3565b5f82019050919050565b5f60a0820190506144e95f83018761404d565b6144f6602083018661404d565b6145036040830185614494565b6145106060830184614494565b8181036080830152614521816144b6565b905095945050505050565b5f614537828961434d565b601482019150614547828861434d565b601482019150614557828761422d565b602082019150614567828661422d565b602082019150614577828561434d565b601482019150614587828461436d565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f6145f5603883614186565b91506146008261459b565b604082019050919050565b5f6020820190508181035f830152614622816145e9565b9050919050565b5f60608201905061463c5f83018661404d565b614649602083018561404d565b6146566040830184614494565b949350505050565b5f614669828a61436d565b602082019150614679828961436d565b602082019150614689828861434d565b601482019150614699828761434d565b6014820191506146a9828661422d565b6020820191506146b9828561422d565b6020820191506146c9828461434d565b60148201915081905098975050505050505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b614728826146e2565b810181811067ffffffffffffffff82111715614747576147466146f2565b5b80604052505050565b5f614759613809565b9050614765828261471f565b919050565b5f60c0828403121561477f5761477e6146de565b5b61478960c0614750565b90505f614798848285016138ec565b5f8301525060206147ab84828501613946565b60208301525060406147bf84828501613946565b60408301525060606147d3848285016138ec565b60608301525060806147e7848285016138ec565b60808301525060a06147fb84828501613dac565b60a08301525092915050565b5f60c0828403121561481c5761481b613812565b5b5f6148298482850161476a565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f61488c602a83614186565b915061489782614832565b604082019050919050565b5f6020820190508181035f8301526148b981614880565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f6148f4601e83614186565b91506148ff826148c0565b602082019050919050565b5f6020820190508181035f830152614921816148e8565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f61495c601e83614186565b915061496782614928565b602082019050919050565b5f6020820190508181035f83015261498981614950565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f6149ea602383614186565b91506149f582614990565b604082019050919050565b5f6020820190508181035f830152614a17816149de565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f614a52601b83614186565b9150614a5d82614a1e565b602082019050919050565b5f6020820190508181035f830152614a7f81614a46565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f614aba601a83614186565b9150614ac582614a86565b602082019050919050565b5f6020820190508181035f830152614ae781614aae565b9050919050565b5f604082019050614b015f83018561446c565b614b0e602083018461446c565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614b4c8261395a565b9150614b578361395a565b9250828201905080821115614b6f57614b6e614b15565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e74206f722054616b6572417070726f7665640000000000602082015250565b5f614bcf603b83614186565b9150614bda82614b75565b604082019050919050565b5f6020820190508181035f830152614bfc81614bc3565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e74207072652d617070726f7665206c6f636b2074696d65000000602082015250565b5f614c5d603d83614186565b9150614c6882614c03565b604082019050919050565b5f6020820190508181035f830152614c8a81614c51565b9050919050565b7f54616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f614ceb602483614186565b9150614cf682614c91565b604082019050919050565b5f6020820190508181035f830152614d1881614cdf565b9050919050565b7f5265636569766572206d757374206e6f74206265207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f614d79602183614186565b9150614d8482614d1f565b604082019050919050565b5f6020820190508181035f830152614da681614d6d565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f614e07602383614186565b9150614e1282614dad565b604082019050919050565b5f6020820190508181035f830152614e3481614dfb565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e20645f8201527f6578206665650000000000000000000000000000000000000000000000000000602082015250565b5f614e95602683614186565b9150614ea082614e3b565b604082019050919050565b5f6020820190508181035f830152614ec281614e89565b9050919050565b5f614ed38261395a565b9150614ede8361395a565b9250828203905081811115614ef657614ef5614b15565b5b92915050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f614f30601d83614186565b9150614f3b82614efc565b602082019050919050565b5f6020820190508181035f830152614f5d81614f24565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f614f98601583614186565b9150614fa382614f64565b602082019050919050565b5f6020820190508181035f830152614fc581614f8c565b9050919050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520545f8201527f616b6572417070726f7665640000000000000000000000000000000000000000602082015250565b5f615026602c83614186565b915061503182614fcc565b604082019050919050565b5f6020820190508181035f8301526150538161501a565b9050919050565b7f4552433230207632207061796d656e7420697320616c726561647920696e69745f8201527f69616c697a656400000000000000000000000000000000000000000000000000602082015250565b5f6150b4602783614186565b91506150bf8261505a565b604082019050919050565b5f6020820190508181035f8301526150e1816150a8565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f61511c601783614186565b9150615127826150e8565b602082019050919050565b5f6020820190508181035f83015261514981615110565b9050919050565b7f44657820666565206d757374206e6f74206265207a65726f00000000000000005f82015250565b5f615184601883614186565b915061518f82615150565b602082019050919050565b5f6020820190508181035f8301526151b181615178565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f615212602b83614186565b915061521d826151b8565b604082019050919050565b5f6020820190508181035f83015261523f81615206565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f61527a601c83614186565b915061528582615246565b602082019050919050565b5f6020820190508181035f8301526152a78161526e565b9050919050565b5f6040820190506152c15f83018561404d565b6152ce6020830184614494565b9392505050565b6152de8161389a565b81146152e8575f80fd5b50565b5f815190506152f9816152d5565b92915050565b5f6020828403121561531457615313613812565b5b5f615321848285016152eb565b9150509291505056fea26469706673582212200d86b0f6898fb823c55626c3b02a7098bc8622606b092e0f458df6c86ce2967864736f6c63430008180033"; -// https://github.com/KomodoPlatform/etomic-swap/blob/006e6fd52334530f23624a2139d0eb5299c4cd10/contracts/EtomicSwapMakerNftV2Test.sol +/// https://github.com/KomodoPlatform/etomic-swap/blob/006e6fd52334530f23624a2139d0eb5299c4cd10/contracts/EtomicSwapMakerNftV2Test.sol pub const NFT_MAKER_SWAP_V2_BYTES: &str = "6080604052348015600e575f80fd5b506131fa8061001c5f395ff3fe608060405234801561000f575f80fd5b50600436106100cd575f3560e01c8063bc197c811161008a578063eb4ab61211610064578063eb4ab61214610209578063efccb9eb14610225578063f0e9fcd114610257578063f23a6e6114610273576100cd565b8063bc197c81146101a1578063c8d9009b146101d1578063c92cd12d146101ed576100cd565b806301ffc9a7146100d157806305ec158d146101015780630f235fce1461011d578063150b7a02146101395780636e6bf6d214610169578063b27e46fb14610185575b5f80fd5b6100eb60048036038101906100e69190612005565b6102a3565b6040516100f8919061204a565b60405180910390f35b61011b60048036038101906101169190612123565b610384565b005b610137600480360381019061013291906121c0565b610644565b005b610153600480360381019061014e91906122aa565b6108fe565b604051610160919061233d565b60405180910390f35b610183600480360381019061017e91906121c0565b610d4d565b005b61019f600480360381019061019a9190612123565b611008565b005b6101bb60048036038101906101b691906123ab565b6112c7565b6040516101c8919061233d565b60405180910390f35b6101eb60048036038101906101e691906121c0565b611303565b005b61020760048036038101906102029190612123565b61162c565b005b610223600480360381019061021e9190612482565b61195a565b005b61023f600480360381019061023a91906124e6565b6119d1565b60405161024e939291906125dc565b60405180910390f35b610271600480360381019061026c9190612611565b611a1d565b005b61028d60048036038101906102889190612661565b611a91565b60405161029a919061233d565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061036d57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061037d575061037c82611f25565b5b9050919050565b6001600381111561039857610397612569565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff1660038111156103ca576103c9612569565b5b1461040a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161040190612777565b60405180910390fd5b5f6003873360028960405160200161042291906127b5565b60405160208183030381529060405260405161043e9190612821565b602060405180830381855afa158015610459573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061047c919061284b565b8888888860405160200161049697969594939291906128db565b6040516020818303038152906040526040516104b29190612821565b602060405180830381855afa1580156104cd573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610557576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161054e906129a5565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561058d5761058c612569565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd73886040516105c191906129d2565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161060c9493929190612a3c565b5f604051808303815f87803b158015610623575f80fd5b505af1158015610635573d5f803e3d5ffd5b50505050505050505050505050565b6001600381111561065857610657612569565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561068a57610689612569565b5b146106ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c190612777565b60405180910390fd5b5f60038633878787876040516020016106e896959493929190612a92565b6040516020818303038152906040526040516107049190612821565b602060405180830381855afa15801561071f573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146107a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107a0906129a5565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610814576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161080b90612b71565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561084a57610849612569565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad192190728760405161087e91906129d2565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016108c793929190612b8f565b5f604051808303815f87803b1580156108de575f80fd5b505af11580156108f0573d5f803e3d5ffd5b505050505050505050505050565b5f80838381019061090f9190612d17565b90505f600381111561092457610923612569565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff16600381111561095957610958612569565b5b14610999576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099090612db2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603610a0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0290612e1a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610a7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7490612e82565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610aef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae690612f10565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610b5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5490612f78565b60405180910390fd5b610b6a8160200151611f8e565b15610baa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba190612fe0565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610bd896959493929190612a92565b604051602081830303815290604052604051610bf49190612821565b602060405180830381855afa158015610c0f573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115610c5f57610c5e612569565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115610cf657610cf5612569565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051610d3091906129d2565b60405180910390a163150b7a0260e01b9250505095945050505050565b60016003811115610d6157610d60612569565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff166003811115610d9357610d92612569565b5b14610dd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dca90612777565b60405180910390fd5b5f60038633600288604051602001610deb91906127b5565b604051602081830303815290604052604051610e079190612821565b602060405180830381855afa158015610e22573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610e45919061284b565b878787604051602001610e5d96959493929190612a92565b604051602081830303815290604052604051610e799190612821565b602060405180830381855afa158015610e94573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610f1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f15906129a5565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610f5457610f53612569565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051610f8891906129d2565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610fd193929190612b8f565b5f604051808303815f87803b158015610fe8575f80fd5b505af1158015610ffa573d5f803e3d5ffd5b505050505050505050505050565b6001600381111561101c5761101b612569565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561104e5761104d612569565b5b1461108e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108590612777565b60405180910390fd5b5f6003873388888888886040516020016110ae97969594939291906128db565b6040516020818303038152906040526040516110ca9190612821565b602060405180830381855afa1580156110e5573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461116f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611166906129a5565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156111da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d190612b71565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156112105761120f612569565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad192190728860405161124491906129d2565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161128f9493929190612a3c565b5f604051808303815f87803b1580156112a6575f80fd5b505af11580156112b8573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112fa90613048565b60405180910390fd5b6001600381111561131757611316612569565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561134957611348612569565b5b14611389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138090612777565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ee906130b0565b60405180910390fd5b5f600333878760028860405160200161141091906127b5565b60405160208183030381529060405260405161142c9190612821565b602060405180830381855afa158015611447573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061146a919061284b565b878760405160200161148196959493929190612a92565b60405160208183030381529060405260405161149d9190612821565b602060405180830381855afa1580156114b8573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611542576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611539906129a5565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561157857611577612569565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0876040516115ac91906129d2565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016115f593929190612b8f565b5f604051808303815f87803b15801561160c575f80fd5b505af115801561161e573d5f803e3d5ffd5b505050505050505050505050565b600160038111156116405761163f612569565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561167257611671612569565b5b146116b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a990612777565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611720576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611717906130b0565b60405180910390fd5b5f600333888860028960405160200161173991906127b5565b6040516020818303038152906040526040516117559190612821565b602060405180830381855afa158015611770573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190611793919061284b565b8888886040516020016117ac97969594939291906128db565b6040516020818303038152906040526040516117c89190612821565b602060405180830381855afa1580156117e3573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461186d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611864906129a5565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156118a3576118a2612569565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0886040516118d791906129d2565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016119229493929190612a3c565b5f604051808303815f87803b158015611939575f80fd5b505af115801561194b573d5f803e3d5ffd5b50505050505050505050505050565b5f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a308487876040518563ffffffff1660e01b815260040161199d9493929190612a3c565b5f604051808303815f87803b1580156119b4575f80fd5b505af11580156119c6573d5f803e3d5ffd5b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3084866040518463ffffffff1660e01b8152600401611a5e93929190612b8f565b5f604051808303815f87803b158015611a75575f80fd5b505af1158015611a87573d5f803e3d5ffd5b5050505050505050565b5f808383810190611aa29190612d17565b90505f6003811115611ab757611ab6612569565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff166003811115611aec57611aeb612569565b5b14611b2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b239061313e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603611b9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9590612e1a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603611c10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c0790612e82565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7990612f10565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614611cf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce790612f78565b60405180910390fd5b5f8511611d32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d29906131a6565b60405180910390fd5b611d3f8160200151611f8e565b15611d7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7690612fe0565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c604051602001611daf97969594939291906128db565b604051602081830303815290604052604051611dcb9190612821565b602060405180830381855afa158015611de6573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115611e3657611e35612569565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115611ecd57611ecc612569565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051611f0791906129d2565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611fe481611fb0565b8114611fee575f80fd5b50565b5f81359050611fff81611fdb565b92915050565b5f6020828403121561201a57612019611fa8565b5b5f61202784828501611ff1565b91505092915050565b5f8115159050919050565b61204481612030565b82525050565b5f60208201905061205d5f83018461203b565b92915050565b5f819050919050565b61207581612063565b811461207f575f80fd5b50565b5f813590506120908161206c565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6120bf82612096565b9050919050565b6120cf816120b5565b81146120d9575f80fd5b50565b5f813590506120ea816120c6565b92915050565b5f819050919050565b612102816120f0565b811461210c575f80fd5b50565b5f8135905061211d816120f9565b92915050565b5f805f805f805f60e0888a03121561213e5761213d611fa8565b5b5f61214b8a828b01612082565b975050602061215c8a828b016120dc565b965050604061216d8a828b01612082565b955050606061217e8a828b01612082565b945050608061218f8a828b016120dc565b93505060a06121a08a828b0161210f565b92505060c06121b18a828b0161210f565b91505092959891949750929550565b5f805f805f8060c087890312156121da576121d9611fa8565b5b5f6121e789828a01612082565b96505060206121f889828a016120dc565b955050604061220989828a01612082565b945050606061221a89828a01612082565b935050608061222b89828a016120dc565b92505060a061223c89828a0161210f565b9150509295509295509295565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261226a57612269612249565b5b8235905067ffffffffffffffff8111156122875761228661224d565b5b6020830191508360018202830111156122a3576122a2612251565b5b9250929050565b5f805f805f608086880312156122c3576122c2611fa8565b5b5f6122d0888289016120dc565b95505060206122e1888289016120dc565b94505060406122f28882890161210f565b935050606086013567ffffffffffffffff81111561231357612312611fac565b5b61231f88828901612255565b92509250509295509295909350565b61233781611fb0565b82525050565b5f6020820190506123505f83018461232e565b92915050565b5f8083601f84011261236b5761236a612249565b5b8235905067ffffffffffffffff8111156123885761238761224d565b5b6020830191508360208202830111156123a4576123a3612251565b5b9250929050565b5f805f805f805f8060a0898b0312156123c7576123c6611fa8565b5b5f6123d48b828c016120dc565b98505060206123e58b828c016120dc565b975050604089013567ffffffffffffffff81111561240657612405611fac565b5b6124128b828c01612356565b9650965050606089013567ffffffffffffffff81111561243557612434611fac565b5b6124418b828c01612356565b9450945050608089013567ffffffffffffffff81111561246457612463611fac565b5b6124708b828c01612255565b92509250509295985092959890939650565b5f805f806080858703121561249a57612499611fa8565b5b5f6124a7878288016120dc565b94505060206124b88782880161210f565b93505060406124c98782880161210f565b92505060606124da878288016120dc565b91505092959194509250565b5f602082840312156124fb576124fa611fa8565b5b5f61250884828501612082565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b61254581612511565b82525050565b5f63ffffffff82169050919050565b6125638161254b565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600481106125a7576125a6612569565b5b50565b5f8190506125b782612596565b919050565b5f6125c6826125aa565b9050919050565b6125d6816125bc565b82525050565b5f6060820190506125ef5f83018661253c565b6125fc602083018561255a565b61260960408301846125cd565b949350505050565b5f805f6060848603121561262857612627611fa8565b5b5f612635868287016120dc565b93505060206126468682870161210f565b9250506040612657868287016120dc565b9150509250925092565b5f805f805f8060a0878903121561267b5761267a611fa8565b5b5f61268889828a016120dc565b965050602061269989828a016120dc565b95505060406126aa89828a0161210f565b94505060606126bb89828a0161210f565b935050608087013567ffffffffffffffff8111156126dc576126db611fac565b5b6126e889828a01612255565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f612761602a836126f7565b915061276c82612707565b604082019050919050565b5f6020820190508181035f83015261278e81612755565b9050919050565b5f819050919050565b6127af6127aa82612063565b612795565b82525050565b5f6127c0828461279e565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6127fb826127cf565b61280581856127d9565b93506128158185602086016127e3565b80840191505092915050565b5f61282c82846127f1565b915081905092915050565b5f815190506128458161206c565b92915050565b5f602082840312156128605761285f611fa8565b5b5f61286d84828501612837565b91505092915050565b5f8160601b9050919050565b5f61288c82612876565b9050919050565b5f61289d82612882565b9050919050565b6128b56128b0826120b5565b612893565b82525050565b5f819050919050565b6128d56128d0826120f0565b6128bb565b82525050565b5f6128e6828a6128a4565b6014820191506128f682896128a4565b601482019150612906828861279e565b602082019150612916828761279e565b60208201915061292682866128a4565b60148201915061293682856128c4565b60208201915061294682846128c4565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f61298f6013836126f7565b915061299a8261295b565b602082019050919050565b5f6020820190508181035f8301526129bc81612983565b9050919050565b6129cc81612063565b82525050565b5f6020820190506129e55f8301846129c3565b92915050565b6129f4816120b5565b82525050565b612a03816120f0565b82525050565b5f82825260208201905092915050565b50565b5f612a275f83612a09565b9150612a3282612a19565b5f82019050919050565b5f60a082019050612a4f5f8301876129eb565b612a5c60208301866129eb565b612a6960408301856129fa565b612a7660608301846129fa565b8181036080830152612a8781612a1c565b905095945050505050565b5f612a9d82896128a4565b601482019150612aad82886128a4565b601482019150612abd828761279e565b602082019150612acd828661279e565b602082019150612add82856128a4565b601482019150612aed82846128c4565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f612b5b6038836126f7565b9150612b6682612b01565b604082019050919050565b5f6020820190508181035f830152612b8881612b4f565b9050919050565b5f606082019050612ba25f8301866129eb565b612baf60208301856129eb565b612bbc60408301846129fa565b949350505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612c0e82612bc8565b810181811067ffffffffffffffff82111715612c2d57612c2c612bd8565b5b80604052505050565b5f612c3f611f9f565b9050612c4b8282612c05565b919050565b612c598161254b565b8114612c63575f80fd5b50565b5f81359050612c7481612c50565b92915050565b5f60c08284031215612c8f57612c8e612bc4565b5b612c9960c0612c36565b90505f612ca884828501612082565b5f830152506020612cbb848285016120dc565b6020830152506040612ccf848285016120dc565b6040830152506060612ce384828501612082565b6060830152506080612cf784828501612082565b60808301525060a0612d0b84828501612c66565b60a08301525092915050565b5f60c08284031215612d2c57612d2b611fa8565b5b5f612d3984828501612c7a565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f612d9c602a836126f7565b9150612da782612d42565b604082019050919050565b5f6020820190508181035f830152612dc981612d90565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612e04601e836126f7565b9150612e0f82612dd0565b602082019050919050565b5f6020820190508181035f830152612e3181612df8565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612e6c601e836126f7565b9150612e7782612e38565b602082019050919050565b5f6020820190508181035f830152612e9981612e60565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f612efa6023836126f7565b9150612f0582612ea0565b604082019050919050565b5f6020820190508181035f830152612f2781612eee565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f612f62601b836126f7565b9150612f6d82612f2e565b602082019050919050565b5f6020820190508181035f830152612f8f81612f56565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f612fca601a836126f7565b9150612fd582612f96565b602082019050919050565b5f6020820190508181035f830152612ff781612fbe565b9050919050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f613032601d836126f7565b915061303d82612ffe565b602082019050919050565b5f6020820190508181035f83015261305f81613026565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f61309a6015836126f7565b91506130a582613066565b602082019050919050565b5f6020820190508181035f8301526130c78161308e565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f613128602b836126f7565b9150613133826130ce565b604082019050919050565b5f6020820190508181035f8301526131558161311c565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f613190601c836126f7565b915061319b8261315c565b602082019050919050565b5f6020820190508181035f8301526131bd81613184565b905091905056fea2646970667358221220c7235610f4c08b95d1e01bd31ff0b8b671c0f18c33212760a2ce3b09e6ad77e964736f6c63430008190033"; +/// https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapMakerNftV2.sol +pub const MAKER_SWAP_V2_BYTES: &str = "6080604052348015600e575f80fd5b50611d9f8061001c5f395ff3fe608060405260043610610054575f3560e01c80631299a27a146100585780637466be601461008057806374a4788a1461009c5780639b949dee146100c4578063a53bc126146100ec578063efccb9eb14610114575b5f80fd5b348015610063575f80fd5b5061007e60048036038101906100799190611427565b610152565b005b61009a600480360381019061009591906114e9565b61044b565b005b3480156100a7575f80fd5b506100c260048036038101906100bd9190611427565b6106fc565b005b3480156100cf575f80fd5b506100ea60048036038101906100e59190611427565b6109f5565b005b3480156100f7575f80fd5b50610112600480360381019061010d9190611560565b610ced565b005b34801561011f575f80fd5b5061013a600480360381019061013591906115fd565b610fd2565b604051610149939291906116e4565b60405180910390f35b6001600381111561016657610165611671565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561019857610197611671565b5b146101d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101cf90611799565b60405180910390fd5b5f6003863387876002886040516020016101f291906117d7565b60405160208183030381529060405260405161020e9190611843565b602060405180830381855afa158015610229573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061024c919061186d565b87604051602001610262969594939291906118fd565b60405160208183030381529060405260405161027e9190611843565b602060405180830381855afa158015610299573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610323576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031a906119b6565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561035957610358611671565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161038d91906119e3565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610411573373ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f1935050505015801561040b573d5f803e3d5ffd5b50610442565b5f82905061044033888373ffffffffffffffffffffffffffffffffffffffff1661101e9092919063ffffffff16565b505b50505050505050565b5f600381111561045e5761045d611671565b5b5f808781526020019081526020015f205f0160189054906101000a900460ff1660038111156104905761048f611671565b5b146104d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c790611a6c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361053e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053590611ad4565b60405180910390fd5b5f3411610580576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057790611b62565b60405180910390fd5b5f600334863387875f60405160200161059e969594939291906118fd565b6040516020818303038152906040526040516105ba9190611843565b602060405180830381855afa1580156105d5573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018363ffffffff1681526020016001600381111561062157610620611671565b5b8152505f808881526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156106b5576106b4611671565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad866040516106ec91906119e3565b60405180910390a1505050505050565b600160038111156107105761070f611671565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561074257610741611671565b5b14610782576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161077990611799565b60405180910390fd5b5f600386863360028860405160200161079b91906117d7565b6040516020818303038152906040526040516107b79190611843565b602060405180830381855afa1580156107d2573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107f5919061186d565b878760405160200161080c969594939291906118fd565b6040516020818303038152906040526040516108289190611843565b602060405180830381855afa158015610843573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146108cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c4906119b6565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561090357610902611671565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd738760405161093791906119e3565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036109bb573373ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f193505050501580156109b5573d5f803e3d5ffd5b506109ec565b5f8290506109ea33888373ffffffffffffffffffffffffffffffffffffffff1661101e9092919063ffffffff16565b505b50505050505050565b60016003811115610a0957610a08611671565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff166003811115610a3b57610a3a611671565b5b14610a7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7290611799565b60405180910390fd5b5f6003868633878787604051602001610a99969594939291906118fd565b604051602081830303815290604052604051610ab59190611843565b602060405180830381855afa158015610ad0573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610b5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b51906119b6565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610bc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbc90611bf0565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610bfb57610bfa611671565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907287604051610c2f91906119e3565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610cb3573373ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f19350505050158015610cad573d5f803e3d5ffd5b50610ce4565b5f829050610ce233888373ffffffffffffffffffffffffffffffffffffffff1661101e9092919063ffffffff16565b505b50505050505050565b5f6003811115610d0057610cff611671565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115610d3257610d31611671565b5b14610d72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6990611a6c565b60405180910390fd5b5f8611610db4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dab90611c58565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610e22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1990611ad4565b60405180910390fd5b5f600387863387878b604051602001610e40969594939291906118fd565b604051602081830303815290604052604051610e5c9190611843565b602060405180830381855afa158015610e77573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018363ffffffff16815260200160016003811115610ec357610ec2611671565b5b8152505f808a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115610f5757610f56611671565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad88604051610f8e91906119e3565b60405180910390a15f869050610fc733308a8473ffffffffffffffffffffffffffffffffffffffff1661109d909392919063ffffffff16565b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b611098838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401611051929190611c94565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061111f565b505050565b611119848573ffffffffffffffffffffffffffffffffffffffff166323b872dd8686866040516024016110d293929190611cbb565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061111f565b50505050565b5f611149828473ffffffffffffffffffffffffffffffffffffffff166111b490919063ffffffff16565b90505f81511415801561116d57508080602001905181019061116b9190611d25565b155b156111af57826040517f5274afe70000000000000000000000000000000000000000000000000000000081526004016111a69190611d50565b60405180910390fd5b505050565b60606111c183835f6111c9565b905092915050565b60608147101561121057306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016112079190611d50565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516112389190611843565b5f6040518083038185875af1925050503d805f8114611272576040519150601f19603f3d011682016040523d82523d5f602084013e611277565b606091505b5091509150611287868383611292565b925050509392505050565b6060826112a7576112a28261131f565b611317565b5f82511480156112cd57505f8473ffffffffffffffffffffffffffffffffffffffff163b145b1561130f57836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016113069190611d50565b60405180910390fd5b819050611318565b5b9392505050565b5f815111156113315780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80fd5b5f819050919050565b61137981611367565b8114611383575f80fd5b50565b5f8135905061139481611370565b92915050565b5f819050919050565b6113ac8161139a565b81146113b6575f80fd5b50565b5f813590506113c7816113a3565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6113f6826113cd565b9050919050565b611406816113ec565b8114611410575f80fd5b50565b5f81359050611421816113fd565b92915050565b5f805f805f8060c0878903121561144157611440611363565b5b5f61144e89828a01611386565b965050602061145f89828a016113b9565b955050604061147089828a01611413565b945050606061148189828a01611386565b935050608061149289828a01611386565b92505060a06114a389828a01611413565b9150509295509295509295565b5f63ffffffff82169050919050565b6114c8816114b0565b81146114d2575f80fd5b50565b5f813590506114e3816114bf565b92915050565b5f805f805f60a0868803121561150257611501611363565b5b5f61150f88828901611386565b955050602061152088828901611413565b945050604061153188828901611386565b935050606061154288828901611386565b9250506080611553888289016114d5565b9150509295509295909350565b5f805f805f805f60e0888a03121561157b5761157a611363565b5b5f6115888a828b01611386565b97505060206115998a828b016113b9565b96505060406115aa8a828b01611413565b95505060606115bb8a828b01611413565b94505060806115cc8a828b01611386565b93505060a06115dd8a828b01611386565b92505060c06115ee8a828b016114d5565b91505092959891949750929550565b5f6020828403121561161257611611611363565b5b5f61161f84828501611386565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b61165c81611628565b82525050565b61166b816114b0565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600481106116af576116ae611671565b5b50565b5f8190506116bf8261169e565b919050565b5f6116ce826116b2565b9050919050565b6116de816116c4565b82525050565b5f6060820190506116f75f830186611653565b6117046020830185611662565b61171160408301846116d5565b949350505050565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f611783602a83611719565b915061178e82611729565b604082019050919050565b5f6020820190508181035f8301526117b081611777565b9050919050565b5f819050919050565b6117d16117cc82611367565b6117b7565b82525050565b5f6117e282846117c0565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f61181d826117f1565b61182781856117fb565b9350611837818560208601611805565b80840191505092915050565b5f61184e8284611813565b915081905092915050565b5f8151905061186781611370565b92915050565b5f6020828403121561188257611881611363565b5b5f61188f84828501611859565b91505092915050565b5f819050919050565b6118b26118ad8261139a565b611898565b82525050565b5f8160601b9050919050565b5f6118ce826118b8565b9050919050565b5f6118df826118c4565b9050919050565b6118f76118f2826113ec565b6118d5565b82525050565b5f61190882896118a1565b60208201915061191882886118e6565b60148201915061192882876118e6565b60148201915061193882866117c0565b60208201915061194882856117c0565b60208201915061195882846118e6565b601482019150819050979650505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f6119a0601383611719565b91506119ab8261196c565b602082019050919050565b5f6020820190508181035f8301526119cd81611994565b9050919050565b6119dd81611367565b82525050565b5f6020820190506119f65f8301846119d4565b92915050565b7f4d616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f611a56602483611719565b9150611a61826119fc565b604082019050919050565b5f6020820190508181035f830152611a8381611a4a565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f611abe601e83611719565b9150611ac982611a8a565b602082019050919050565b5f6020820190508181035f830152611aeb81611ab2565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f611b4c602383611719565b9150611b5782611af2565b604082019050919050565b5f6020820190508181035f830152611b7981611b40565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f611bda603883611719565b9150611be582611b80565b604082019050919050565b5f6020820190508181035f830152611c0781611bce565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f611c42601783611719565b9150611c4d82611c0e565b602082019050919050565b5f6020820190508181035f830152611c6f81611c36565b9050919050565b611c7f816113ec565b82525050565b611c8e8161139a565b82525050565b5f604082019050611ca75f830185611c76565b611cb46020830184611c85565b9392505050565b5f606082019050611cce5f830186611c76565b611cdb6020830185611c76565b611ce86040830184611c85565b949350505050565b5f8115159050919050565b611d0481611cf0565b8114611d0e575f80fd5b50565b5f81519050611d1f81611cfb565b92915050565b5f60208284031215611d3a57611d39611363565b5b5f611d4784828501611d11565b91505092915050565b5f602082019050611d635f830184611c76565b9291505056fea2646970667358221220565f86096f083c176a08cc3c220c01bd63eb7268584f034f3380299de3dac57f64736f6c63430008190033"; +/// https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapTakerV2.sol +pub const TAKER_SWAP_V2_BYTES: &str = "60a060405234801561000f575f80fd5b50604051612a1b380380612a1b83398181016040528101906100319190610137565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361009f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610096906101e2565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505050610200565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610106826100dd565b9050919050565b610116816100fc565b8114610120575f80fd5b50565b5f815190506101318161010d565b92915050565b5f6020828403121561014c5761014b6100d9565b5b5f61015984828501610123565b91505092915050565b5f82825260208201905092915050565b7f66656541646472657373206d757374206e6f74206265207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f6101cc602383610162565b91506101d782610172565b604082019050919050565b5f6020820190508181035f8301526101f9816101c0565b9050919050565b6080516127f56102265f395f818161116d0152818161120801526115c401526127f55ff3fe60806040526004361061007a575f3560e01c80639b4603f21161004d5780639b4603f214610135578063cc90c19914610151578063d6a71eb414610179578063e06cf966146101a15761007a565b8063146e5b241461007e5780633e6af5f2146100a657806346b95ac7146100ce57806365e266171461010d575b5f80fd5b348015610089575f80fd5b506100a4600480360381019061009f91906119ef565b6101cb565b005b3480156100b1575f80fd5b506100cc60048036038101906100c791906119ef565b6103ae565b005b3480156100d9575f80fd5b506100f460048036038101906100ef9190611a8c565b6106bc565b6040516101049493929190611b82565b60405180910390f35b348015610118575f80fd5b50610133600480360381019061012e91906119ef565b61071d565b005b61014f600480360381019061014a9190611bef565b610b79565b005b34801561015c575f80fd5b50610177600480360381019061017291906119ef565b610ead565b005b348015610184575f80fd5b5061019f600480360381019061019a9190611c8c565b61125a565b005b3480156101ac575f80fd5b506101b56115c2565b6040516101c29190611d5f565b60405180910390f35b600160048111156101df576101de611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff16600481111561021157610210611b0f565b5b14610251576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024890611df8565b60405180910390fd5b5f6003878787338888886040516020016102719796959493929190611e9b565b60405160208183030381529060405260405161028d9190611f6d565b602060405180830381855afa1580156102a8573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610332576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032990611fcd565b60405180910390fd5b60025f808a81526020019081526020015f205f01601c6101000a81548160ff0219169083600481111561036857610367611b0f565b5b02179055507f9c45e43e2ef051f70491ffd5221bf02ab37e1324128714ef9610df5f24fc9fb58860405161039c9190611ffa565b60405180910390a15050505050505050565b600160048111156103c2576103c1611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660048111156103f4576103f3611b0f565b5b14610434576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042b90611df8565b60405180910390fd5b5f60038787873360028960405160200161044e9190612013565b60405160208183030381529060405260405161046a9190611f6d565b602060405180830381855afa158015610485573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906104a89190612041565b88886040516020016104c09796959493929190611e9b565b6040516020818303038152906040526040516104dc9190611f6d565b602060405180830381855afa1580156104f7573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610581576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057890611fcd565b60405180910390fd5b60045f808a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156105b7576105b6611b0f565b5b02179055507f45169a52eef651b20a81474b50b8a5d83225225fcd097ef3cf7952d9ab304f2788856040516105ed92919061206c565b60405180910390a15f868861060291906120c0565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610680573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f1935050505015801561067a573d5f803e3d5ffd5b506106b1565b5f8390506106af33838373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900463ffffffff1690805f01601c9054906101000a900460ff16905084565b6001600481111561073157610730611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff16600481111561076357610762611b0f565b5b14806107b257506002600481111561077e5761077d611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660048111156107b0576107af611b0f565b5b145b6107f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e890612163565b60405180910390fd5b5f6003878787338888886040516020016108119796959493929190611e9b565b60405160208183030381529060405260405161082d9190611f6d565b602060405180830381855afa158015610848573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146108d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c990611fcd565b60405180910390fd5b600260048111156108e6576108e5611b0f565b5b5f808a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561091857610917611b0f565b5b03610989575f808981526020019081526020015f205f0160189054906101000a900463ffffffff1663ffffffff16421015610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097f906121f1565b60405180910390fd5b5b6001600481111561099d5761099c611b0f565b5b5f808a81526020019081526020015f205f01601c9054906101000a900460ff1660048111156109cf576109ce611b0f565b5b03610a40575f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610a3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a369061227f565b60405180910390fd5b5b60045f808a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610a7657610a75611b0f565b5b02179055507fbdd7a4be6d82798a500b59077706b12d3f45acf5504828919f92501307b2b95388604051610aaa9190611ffa565b60405180910390a15f8688610abf91906120c0565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b3d573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015610b37573d5f803e3d5ffd5b50610b6e565b5f839050610b6c33838373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b505050505050505050565b5f6004811115610b8c57610b8b611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff166004811115610bbe57610bbd611b0f565b5b14610bfe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf59061230d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610c6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c639061239b565b60405180910390fd5b5f3411610cae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca590612429565b60405180910390fd5b853411610cf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce7906124b7565b60405180910390fd5b5f60038734610cff91906124d5565b88883389895f604051602001610d1b9796959493929190611e9b565b604051602081830303815290604052604051610d379190611f6d565b602060405180830381855afa158015610d52573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115610daa57610da9611b0f565b5b8152505f808a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115610e6457610e63611b0f565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd93588604051610e9b9190611ffa565b60405180910390a15050505050505050565b60026004811115610ec157610ec0611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff166004811115610ef357610ef2611b0f565b5b14610f33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2a90612578565b60405180910390fd5b5f60038787338888600289604051602001610f4e9190612013565b604051602081830303815290604052604051610f6a9190611f6d565b602060405180830381855afa158015610f85573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610fa89190612041565b88604051602001610fbf9796959493929190611e9b565b604051602081830303815290604052604051610fdb9190611f6d565b602060405180830381855afa158015610ff6573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611080576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107790611fcd565b60405180910390fd5b60035f808a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156110b6576110b5611b0f565b5b02179055507f0d0da0df275f85bed3a5fe7ae79f3559341a3f9ccd8e010133438135bda00a8788846040516110ec92919061206c565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111d4573373ffffffffffffffffffffffffffffffffffffffff166108fc8890811502906040515f60405180830381858888f1935050505015801561116a573d5f803e3d5ffd5b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f193505050501580156111ce573d5f803e3d5ffd5b50611250565b5f82905061120333898373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b61124e7f0000000000000000000000000000000000000000000000000000000000000000888373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b5050505050505050565b5f600481111561126d5761126c611b0f565b5b5f808b81526020019081526020015f205f01601c9054906101000a900460ff16600481111561129f5761129e611b0f565b5b146112df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d690612606565b60405180910390fd5b5f8811611321576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113189061266e565b60405180910390fd5b5f8711611363576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135a906126d6565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c89061239b565b60405180910390fd5b5f60038989883389898d6040516020016113f19796959493929190611e9b565b60405160208183030381529060405260405161140d9190611f6d565b602060405180830381855afa158015611428573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff168152602001600160048111156114805761147f611b0f565b5b8152505f808c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff0219169083600481111561153a57611539611b0f565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358a6040516115719190611ffa565b60405180910390a15f8790506115b533308b8d61158e91906120c0565b8473ffffffffffffffffffffffffffffffffffffffff16611665909392919063ffffffff16565b5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b611660838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401611619929190612703565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506116e7565b505050565b6116e1848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161169a9392919061272a565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506116e7565b50505050565b5f611711828473ffffffffffffffffffffffffffffffffffffffff1661177c90919063ffffffff16565b90505f8151141580156117355750808060200190518101906117339190612794565b155b1561177757826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161176e9190611d5f565b60405180910390fd5b505050565b606061178983835f611791565b905092915050565b6060814710156117d857306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016117cf9190611d5f565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516118009190611f6d565b5f6040518083038185875af1925050503d805f811461183a576040519150601f19603f3d011682016040523d82523d5f602084013e61183f565b606091505b509150915061184f86838361185a565b925050509392505050565b60608261186f5761186a826118e7565b6118df565b5f825114801561189557505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156118d757836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016118ce9190611d5f565b60405180910390fd5b8190506118e0565b5b9392505050565b5f815111156118f95780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80fd5b5f819050919050565b6119418161192f565b811461194b575f80fd5b50565b5f8135905061195c81611938565b92915050565b5f819050919050565b61197481611962565b811461197e575f80fd5b50565b5f8135905061198f8161196b565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6119be82611995565b9050919050565b6119ce816119b4565b81146119d8575f80fd5b50565b5f813590506119e9816119c5565b92915050565b5f805f805f805f60e0888a031215611a0a57611a0961192b565b5b5f611a178a828b0161194e565b9750506020611a288a828b01611981565b9650506040611a398a828b01611981565b9550506060611a4a8a828b016119db565b9450506080611a5b8a828b0161194e565b93505060a0611a6c8a828b0161194e565b92505060c0611a7d8a828b016119db565b91505092959891949750929550565b5f60208284031215611aa157611aa061192b565b5b5f611aae8482850161194e565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b611aeb81611ab7565b82525050565b5f63ffffffff82169050919050565b611b0981611af1565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60058110611b4d57611b4c611b0f565b5b50565b5f819050611b5d82611b3c565b919050565b5f611b6c82611b50565b9050919050565b611b7c81611b62565b82525050565b5f608082019050611b955f830187611ae2565b611ba26020830186611b00565b611baf6040830185611b00565b611bbc6060830184611b73565b95945050505050565b611bce81611af1565b8114611bd8575f80fd5b50565b5f81359050611be981611bc5565b92915050565b5f805f805f805f60e0888a031215611c0a57611c0961192b565b5b5f611c178a828b0161194e565b9750506020611c288a828b01611981565b9650506040611c398a828b016119db565b9550506060611c4a8a828b0161194e565b9450506080611c5b8a828b0161194e565b93505060a0611c6c8a828b01611bdb565b92505060c0611c7d8a828b01611bdb565b91505092959891949750929550565b5f805f805f805f805f6101208a8c031215611caa57611ca961192b565b5b5f611cb78c828d0161194e565b9950506020611cc88c828d01611981565b9850506040611cd98c828d01611981565b9750506060611cea8c828d016119db565b9650506080611cfb8c828d016119db565b95505060a0611d0c8c828d0161194e565b94505060c0611d1d8c828d0161194e565b93505060e0611d2e8c828d01611bdb565b925050610100611d408c828d01611bdb565b9150509295985092959850929598565b611d59816119b4565b82525050565b5f602082019050611d725f830184611d50565b92915050565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f611de2602a83611d78565b9150611ded82611d88565b604082019050919050565b5f6020820190508181035f830152611e0f81611dd6565b9050919050565b5f819050919050565b611e30611e2b82611962565b611e16565b82525050565b5f8160601b9050919050565b5f611e4c82611e36565b9050919050565b5f611e5d82611e42565b9050919050565b611e75611e70826119b4565b611e53565b82525050565b5f819050919050565b611e95611e908261192f565b611e7b565b82525050565b5f611ea6828a611e1f565b602082019150611eb68289611e1f565b602082019150611ec68288611e64565b601482019150611ed68287611e64565b601482019150611ee68286611e84565b602082019150611ef68285611e84565b602082019150611f068284611e64565b60148201915081905098975050505050505050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f611f4782611f1b565b611f518185611f25565b9350611f61818560208601611f2f565b80840191505092915050565b5f611f788284611f3d565b915081905092915050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f611fb7601383611d78565b9150611fc282611f83565b602082019050919050565b5f6020820190508181035f830152611fe481611fab565b9050919050565b611ff48161192f565b82525050565b5f60208201905061200d5f830184611feb565b92915050565b5f61201e8284611e84565b60208201915081905092915050565b5f8151905061203b81611938565b92915050565b5f602082840312156120565761205561192b565b5b5f6120638482850161202d565b91505092915050565b5f60408201905061207f5f830185611feb565b61208c6020830184611feb565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6120ca82611962565b91506120d583611962565b92508282019050808211156120ed576120ec612093565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e74206f722054616b6572417070726f7665640000000000602082015250565b5f61214d603b83611d78565b9150612158826120f3565b604082019050919050565b5f6020820190508181035f83015261217a81612141565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f6121db603883611d78565b91506121e682612181565b604082019050919050565b5f6020820190508181035f830152612208816121cf565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e74207072652d617070726f7665206c6f636b2074696d65000000602082015250565b5f612269603d83611d78565b91506122748261220f565b604082019050919050565b5f6020820190508181035f8301526122968161225d565b9050919050565b7f54616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f6122f7602483611d78565b91506123028261229d565b604082019050919050565b5f6020820190508181035f830152612324816122eb565b9050919050565b7f5265636569766572206d757374206e6f74206265207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f612385602183611d78565b91506123908261232b565b604082019050919050565b5f6020820190508181035f8301526123b281612379565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f612413602383611d78565b915061241e826123b9565b604082019050919050565b5f6020820190508181035f83015261244081612407565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e20645f8201527f6578206665650000000000000000000000000000000000000000000000000000602082015250565b5f6124a1602683611d78565b91506124ac82612447565b604082019050919050565b5f6020820190508181035f8301526124ce81612495565b9050919050565b5f6124df82611962565b91506124ea83611962565b925082820390508181111561250257612501612093565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520545f8201527f616b6572417070726f7665640000000000000000000000000000000000000000602082015250565b5f612562602c83611d78565b915061256d82612508565b604082019050919050565b5f6020820190508181035f83015261258f81612556565b9050919050565b7f4552433230207632207061796d656e7420697320616c726561647920696e69745f8201527f69616c697a656400000000000000000000000000000000000000000000000000602082015250565b5f6125f0602783611d78565b91506125fb82612596565b604082019050919050565b5f6020820190508181035f83015261261d816125e4565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f612658601783611d78565b915061266382612624565b602082019050919050565b5f6020820190508181035f8301526126858161264c565b9050919050565b7f44657820666565206d757374206e6f74206265207a65726f00000000000000005f82015250565b5f6126c0601883611d78565b91506126cb8261268c565b602082019050919050565b5f6020820190508181035f8301526126ed816126b4565b9050919050565b6126fd81611962565b82525050565b5f6040820190506127165f830185611d50565b61272360208301846126f4565b9392505050565b5f60608201905061273d5f830186611d50565b61274a6020830185611d50565b61275760408301846126f4565b949350505050565b5f8115159050919050565b6127738161275f565b811461277d575f80fd5b50565b5f8151905061278e8161276a565b92915050565b5f602082840312156127a9576127a861192b565b5b5f6127b684828501612780565b9150509291505056fea2646970667358221220fd2a736cddd6ebbd2831b0e65fb5470ffebd789dc32c1d3782ce69362e16fae564736f6c63430008190033"; pub trait CoinDockerOps { fn rpc_client(&self) -> &UtxoRpcClientEnum; @@ -1168,6 +1168,105 @@ pub fn init_geth_node() { thread::sleep(Duration::from_millis(100)); } + let tx_request_deploy_maker_swap_contract_v2 = TransactionRequest { + from: GETH_ACCOUNT, + to: None, + gas: None, + gas_price: None, + value: None, + data: Some(hex::decode(MAKER_SWAP_V2_BYTES).unwrap().into()), + nonce: None, + condition: None, + transaction_type: None, + access_list: None, + max_fee_per_gas: None, + max_priority_fee_per_gas: None, + }; + let deploy_maker_swap_v2_tx_hash = block_on( + GETH_WEB3 + .eth() + .send_transaction(tx_request_deploy_maker_swap_contract_v2), + ) + .unwrap(); + log!( + "Sent deploy maker swap v2 contract transaction {:?}", + deploy_maker_swap_v2_tx_hash + ); + + loop { + let deploy_maker_swap_v2_tx_receipt = + match block_on(GETH_WEB3.eth().transaction_receipt(deploy_maker_swap_v2_tx_hash)) { + Ok(receipt) => receipt, + Err(_) => { + thread::sleep(Duration::from_millis(100)); + continue; + }, + }; + + if let Some(receipt) = deploy_maker_swap_v2_tx_receipt { + GETH_MAKER_SWAP_V2 = receipt.contract_address.unwrap(); + log!( + "GETH_MAKER_SWAP_V2 contract address: {:?}, receipt.status: {:?}", + GETH_MAKER_SWAP_V2, + receipt.status + ); + break; + } + thread::sleep(Duration::from_millis(100)); + } + + let dex_fee_addr = addr_from_raw_pubkey(&DEX_FEE_ADDR_RAW_PUBKEY).unwrap(); + let dex_fee_addr = Token::Address(dex_fee_addr); + let params = ethabi::encode(&[dex_fee_addr]); + let taker_swap_v2_data = format!("{}{}", TAKER_SWAP_V2_BYTES, hex::encode(params)); + + let tx_request_deploy_taker_swap_contract_v2 = TransactionRequest { + from: GETH_ACCOUNT, + to: None, + gas: None, + gas_price: None, + value: None, + data: Some(hex::decode(taker_swap_v2_data).unwrap().into()), + nonce: None, + condition: None, + transaction_type: None, + access_list: None, + max_fee_per_gas: None, + max_priority_fee_per_gas: None, + }; + let deploy_taker_swap_v2_tx_hash = block_on( + GETH_WEB3 + .eth() + .send_transaction(tx_request_deploy_taker_swap_contract_v2), + ) + .unwrap(); + log!( + "Sent deploy taker swap v2 contract transaction {:?}", + deploy_taker_swap_v2_tx_hash + ); + + loop { + let deploy_taker_swap_v2_tx_receipt = + match block_on(GETH_WEB3.eth().transaction_receipt(deploy_taker_swap_v2_tx_hash)) { + Ok(receipt) => receipt, + Err(_) => { + thread::sleep(Duration::from_millis(100)); + continue; + }, + }; + + if let Some(receipt) = deploy_taker_swap_v2_tx_receipt { + GETH_TAKER_SWAP_V2 = receipt.contract_address.unwrap(); + log!( + "GETH_TAKER_SWAP_V2 contract address: {:?}, receipt.status: {:?}", + GETH_TAKER_SWAP_V2, + receipt.status + ); + break; + } + thread::sleep(Duration::from_millis(100)); + } + let tx_request_deploy_watchers_swap_contract = TransactionRequest { from: GETH_ACCOUNT, to: None, @@ -1205,7 +1304,7 @@ pub fn init_geth_node() { if let Some(receipt) = deploy_watchers_swap_tx_receipt { GETH_WATCHERS_SWAP_CONTRACT = receipt.contract_address.unwrap(); - log!("GETH_WATCHERS_SWAP_CONTRACT {:?}", GETH_SWAP_CONTRACT); + log!("GETH_WATCHERS_SWAP_CONTRACT {:?}", GETH_WATCHERS_SWAP_CONTRACT); break; } thread::sleep(Duration::from_millis(100)); @@ -1249,7 +1348,7 @@ pub fn init_geth_node() { if let Some(receipt) = deploy_nft_maker_swap_v2_tx_receipt { GETH_NFT_MAKER_SWAP_V2 = receipt.contract_address.unwrap(); log!( - "GETH_NFT_MAKER_SWAP_V2 {:?}, receipt.status {:?}", + "GETH_NFT_MAKER_SWAP_V2 contact address: {:?}, receipt.status: {:?}", GETH_NFT_MAKER_SWAP_V2, receipt.status ); diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs index 330dec30de..f4555264fa 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs @@ -1,6 +1,7 @@ use crate::docker_tests::docker_tests_common::{generate_utxo_coin_with_privkey, trade_base_rel, GETH_RPC_URL, MM_CTX}; use crate::docker_tests::eth_docker_tests::{erc20_coin_with_random_privkey, erc20_contract_checksum, - fill_eth_erc20_with_private_key, swap_contract}; + fill_eth_erc20_with_private_key, init_swap_contract_addresses, + swap_contract}; use crate::integration_tests_common::*; use crate::{fill_address, generate_utxo_coin_with_random_privkey, random_secp256k1_secret, rmd160_from_priv, utxo_coin_from_privkey}; @@ -3589,6 +3590,8 @@ async fn enable_eth_with_tokens( "ticker": platform_coin, "erc20_tokens_requests": erc20_tokens_requests, "swap_contract_address": swap_contract_address, + "maker_swap_v2_contract": swap_contract_address, + "taker_swap_v2_contract": swap_contract_address, "nodes": nodes, "tx_history": true, "get_balances": balance, @@ -3607,7 +3610,7 @@ async fn enable_eth_with_tokens( #[test] fn test_enable_eth_coin_with_token_then_disable() { - let coin = erc20_coin_with_random_privkey(swap_contract()); + let coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); let priv_key = coin.display_priv_key().unwrap(); let coins = json!([eth_dev_conf(), erc20_dev_conf(&erc20_contract_checksum())]); @@ -3666,7 +3669,7 @@ fn test_enable_eth_coin_with_token_then_disable() { #[test] fn test_enable_eth_coin_with_token_without_balance() { - let coin = erc20_coin_with_random_privkey(swap_contract()); + let coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); let priv_key = coin.display_priv_key().unwrap(); let coins = json!([eth_dev_conf(), erc20_dev_conf(&erc20_contract_checksum())]); @@ -3715,8 +3718,8 @@ fn test_enable_eth_coin_with_token_without_balance() { #[test] fn test_eth_swap_contract_addr_negotiation_same_fallback() { - let bob_coin = erc20_coin_with_random_privkey(swap_contract()); - let alice_coin = erc20_coin_with_random_privkey(swap_contract()); + let bob_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); let bob_priv_key = bob_coin.display_priv_key().unwrap(); let alice_priv_key = alice_coin.display_priv_key().unwrap(); @@ -3808,8 +3811,8 @@ fn test_eth_swap_contract_addr_negotiation_same_fallback() { #[test] fn test_eth_swap_negotiation_fails_maker_no_fallback() { - let bob_coin = erc20_coin_with_random_privkey(swap_contract()); - let alice_coin = erc20_coin_with_random_privkey(swap_contract()); + let bob_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); let bob_priv_key = bob_coin.display_priv_key().unwrap(); let alice_priv_key = alice_coin.display_priv_key().unwrap(); @@ -4373,7 +4376,7 @@ fn test_gtc_taker_order_should_transform_to_maker() { #[test] fn test_set_price_must_save_order_to_db() { - let private_key_str = erc20_coin_with_random_privkey(swap_contract()) + let private_key_str = erc20_coin_with_random_privkey(init_swap_contract_addresses()) .display_priv_key() .unwrap(); let coins = json!([eth_dev_conf(), erc20_dev_conf(&erc20_contract_checksum())]); @@ -4534,7 +4537,7 @@ fn test_sell_response_format() { #[test] fn test_set_price_conf_settings() { - let private_key_str = erc20_coin_with_random_privkey(swap_contract()) + let private_key_str = erc20_coin_with_random_privkey(init_swap_contract_addresses()) .display_priv_key() .unwrap(); @@ -4607,7 +4610,7 @@ fn test_set_price_conf_settings() { #[test] fn test_buy_conf_settings() { - let private_key_str = erc20_coin_with_random_privkey(swap_contract()) + let private_key_str = erc20_coin_with_random_privkey(init_swap_contract_addresses()) .display_priv_key() .unwrap(); @@ -4680,7 +4683,7 @@ fn test_buy_conf_settings() { #[test] fn test_sell_conf_settings() { - let private_key_str = erc20_coin_with_random_privkey(swap_contract()) + let private_key_str = erc20_coin_with_random_privkey(init_swap_contract_addresses()) .display_priv_key() .unwrap(); @@ -4814,8 +4817,8 @@ fn test_my_orders_response_format() { #[test] fn test_my_orders_after_matched() { - let bob_coin = erc20_coin_with_random_privkey(swap_contract()); - let alice_coin = erc20_coin_with_random_privkey(swap_contract()); + let bob_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); let coins = json!([eth_dev_conf(), erc20_dev_conf(&erc20_contract_checksum())]); @@ -4910,8 +4913,8 @@ fn test_my_orders_after_matched() { #[test] fn test_update_maker_order_after_matched() { - let bob_coin = erc20_coin_with_random_privkey(swap_contract()); - let alice_coin = erc20_coin_with_random_privkey(swap_contract()); + let bob_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); let coins = json!([eth_dev_conf(), erc20_dev_conf(&erc20_contract_checksum())]); diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index a718199f47..05c911caf8 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1,9 +1,9 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC721_TEST_ABI, GETH_ACCOUNT, - GETH_ERC1155_CONTRACT, GETH_ERC20_CONTRACT, GETH_ERC721_CONTRACT, + GETH_ERC1155_CONTRACT, GETH_ERC20_CONTRACT, GETH_ERC721_CONTRACT, GETH_MAKER_SWAP_V2, GETH_NFT_MAKER_SWAP_V2, GETH_NFT_SWAP_CONTRACT, GETH_NONCE_LOCK, GETH_RPC_URL, - GETH_SWAP_CONTRACT, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, MM_CTX, - SEPOLIA_ERC1155_CONTRACT, SEPOLIA_ERC721_CONTRACT, SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2, - SEPOLIA_NONCE_LOCK, SEPOLIA_RPC_URL, SEPOLIA_WEB3}; + GETH_SWAP_CONTRACT, GETH_TAKER_SWAP_V2, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, + MM_CTX, SEPOLIA_ERC1155_CONTRACT, SEPOLIA_ERC721_CONTRACT, + SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2, SEPOLIA_NONCE_LOCK, SEPOLIA_RPC_URL, SEPOLIA_WEB3}; use crate::common::Future01CompatExt; use bitcrypto::{dhash160, sha256}; use coins::eth::gas_limit::ETH_MAX_TRADE_GAS; @@ -45,6 +45,16 @@ pub fn geth_account() -> Address { unsafe { GETH_ACCOUNT } } /// GETH_SWAP_CONTRACT is set once during initialization before tests start pub fn swap_contract() -> Address { unsafe { GETH_SWAP_CONTRACT } } +/// # Safety +/// +/// GETH_MAKER_SWAP_V2 is set once during initialization before tests start +pub fn maker_swap_v2() -> Address { unsafe { GETH_MAKER_SWAP_V2 } } + +/// # Safety +/// +/// GETH_TAKER_SWAP_V2 is set once during initialization before tests start +pub fn taker_swap_v2() -> Address { unsafe { GETH_TAKER_SWAP_V2 } } + #[allow(dead_code)] /// # Safety /// @@ -265,12 +275,15 @@ pub(crate) async fn fill_erc721_info(eth_coin: &EthCoin, token_address: Address, } /// Creates ETH protocol coin supplied with 100 ETH -pub fn eth_coin_with_random_privkey_using_urls(swap_contract_address: Address, urls: &[&str]) -> EthCoin { +pub fn eth_coin_with_random_privkey_using_urls(swap_addresses: SwapAddressesWrapper, urls: &[&str]) -> EthCoin { let eth_conf = eth_dev_conf(); let req = json!({ "method": "enable", "coin": "ETH", - "swap_contract_address": swap_contract_address, + "swap_contract_address": swap_addresses.swap_contract_address, + "maker_swap_v2_contract": swap_addresses.maker_swap_v2_contract, + "taker_swap_v2_contract": swap_addresses.taker_swap_v2_contract, + "nft_maker_swap_v2_contract": swap_addresses.nft_maker_swap_v2_contract, "urls": urls, }); @@ -296,18 +309,38 @@ pub fn eth_coin_with_random_privkey_using_urls(swap_contract_address: Address, u eth_coin } +#[derive(Clone, Debug)] +pub struct SwapAddressesWrapper { + pub swap_contract_address: Address, + pub maker_swap_v2_contract: Address, + pub taker_swap_v2_contract: Address, + pub nft_maker_swap_v2_contract: Address, +} + +pub fn init_swap_contract_addresses() -> SwapAddressesWrapper { + SwapAddressesWrapper { + swap_contract_address: swap_contract(), + maker_swap_v2_contract: maker_swap_v2(), + taker_swap_v2_contract: taker_swap_v2(), + nft_maker_swap_v2_contract: geth_nft_maker_swap_v2(), + } +} + /// Creates ETH protocol coin supplied with 100 ETH, using the default GETH_RPC_URL -pub fn eth_coin_with_random_privkey(swap_contract_address: Address) -> EthCoin { - eth_coin_with_random_privkey_using_urls(swap_contract_address, &[GETH_RPC_URL]) +pub fn eth_coin_with_random_privkey(swap_addresses: SwapAddressesWrapper) -> EthCoin { + eth_coin_with_random_privkey_using_urls(swap_addresses, &[GETH_RPC_URL]) } /// Creates ERC20 protocol coin supplied with 1 ETH and 100 token -pub fn erc20_coin_with_random_privkey(swap_contract_address: Address) -> EthCoin { +pub fn erc20_coin_with_random_privkey(swap_addresses: SwapAddressesWrapper) -> EthCoin { let erc20_conf = erc20_dev_conf(&erc20_contract_checksum()); let req = json!({ "method": "enable", "coin": "ERC20DEV", - "swap_contract_address": swap_contract_address, + "swap_contract_address": swap_addresses.swap_contract_address, + "maker_swap_v2_contract": swap_addresses.maker_swap_v2_contract, + "taker_swap_v2_contract": swap_addresses.taker_swap_v2_contract, + "nft_maker_swap_v2_contract": swap_addresses.nft_maker_swap_v2_contract, "urls": [GETH_RPC_URL], }); @@ -346,13 +379,16 @@ pub enum TestNftType { /// Generates a global NFT coin instance with a random private key and an initial 100 ETH balance. /// Optionally mints a specified NFT (either ERC721 or ERC1155) to the global NFT address, /// with details recorded in the `nfts_infos` field based on the provided `nft_type`. -pub fn global_nft_with_random_privkey(swap_contract_address: Address, nft_type: Option) -> EthCoin { +pub fn global_nft_with_random_privkey(swap_addresses: SwapAddressesWrapper, nft_type: Option) -> EthCoin { let nft_conf = nft_dev_conf(); let req = json!({ "method": "enable", "coin": "NFT_ETH", "urls": [GETH_RPC_URL], - "swap_contract_address": swap_contract_address, + "swap_contract_address": swap_addresses.swap_contract_address, + "maker_swap_v2_contract": swap_addresses.maker_swap_v2_contract, + "taker_swap_v2_contract": swap_addresses.taker_swap_v2_contract, + "nft_maker_swap_v2_contract": swap_addresses.nft_maker_swap_v2_contract, }); let global_nft = block_on(eth_coin_from_conf_and_request( @@ -395,7 +431,7 @@ pub fn global_nft_with_random_privkey(swap_contract_address: Address, nft_type: /// Can be used to generate global NFT from Sepolia Maker/Taker priv keys. fn global_nft_from_privkey( ctx: &MmArc, - swap_contract_address: Address, + swap_addresses: SwapAddressesWrapper, secret: &'static str, nft_type: Option, ) -> EthCoin { @@ -404,7 +440,10 @@ fn global_nft_from_privkey( "method": "enable", "coin": "NFT_ETH", "urls": [SEPOLIA_RPC_URL], - "swap_contract_address": swap_contract_address, + "swap_contract_address": swap_addresses.swap_contract_address, + "maker_swap_v2_contract": swap_addresses.maker_swap_v2_contract, + "taker_swap_v2_contract": swap_addresses.taker_swap_v2_contract, + "nft_maker_swap_v2_contract": swap_addresses.nft_maker_swap_v2_contract, }); let priv_key = Secp256k1Secret::from(secret); @@ -504,6 +543,9 @@ pub fn fill_eth_erc20_with_private_key(priv_key: Secp256k1Secret) { "coin": "ETH", "urls": [GETH_RPC_URL], "swap_contract_address": swap_contract(), + "maker_swap_v2_contract": maker_swap_v2(), + "taker_swap_v2_contract": taker_swap_v2(), + "nft_maker_swap_v2_contract": geth_nft_maker_swap_v2(), }); let eth_coin = block_on(eth_coin_from_conf_and_request( @@ -526,6 +568,9 @@ pub fn fill_eth_erc20_with_private_key(priv_key: Secp256k1Secret) { "coin": "ERC20DEV", "urls": [GETH_RPC_URL], "swap_contract_address": swap_contract(), + "maker_swap_v2_contract": maker_swap_v2(), + "taker_swap_v2_contract": taker_swap_v2(), + "nft_maker_swap_v2_contract": geth_nft_maker_swap_v2(), }); let _erc20_coin = block_on(eth_coin_from_conf_and_request( @@ -546,7 +591,7 @@ pub fn fill_eth_erc20_with_private_key(priv_key: Secp256k1Secret) { } fn send_and_refund_eth_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { - let eth_coin = eth_coin_with_random_privkey(swap_contract()); + let eth_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); eth_coin.set_swap_transaction_fee_policy(swap_txfee_policy); let time_lock = now_sec() - 100; @@ -628,8 +673,9 @@ fn send_and_refund_eth_maker_payment_internal_gas_policy() { fn send_and_refund_eth_maker_payment_priority_fee() { send_and_refund_eth_maker_payment_impl(SwapTxFeePolicy::Medium); } fn send_and_spend_eth_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { - let maker_eth_coin = eth_coin_with_random_privkey(swap_contract()); - let taker_eth_coin = eth_coin_with_random_privkey(swap_contract()); + let swap_addresses = init_swap_contract_addresses(); + let maker_eth_coin = eth_coin_with_random_privkey(swap_addresses.clone()); + let taker_eth_coin = eth_coin_with_random_privkey(swap_addresses); maker_eth_coin.set_swap_transaction_fee_policy(swap_txfee_policy.clone()); taker_eth_coin.set_swap_transaction_fee_policy(swap_txfee_policy); @@ -714,7 +760,7 @@ fn send_and_spend_eth_maker_payment_priority_fee() { send_and_spend_eth_maker_pa fn send_and_refund_erc20_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { thread::sleep(Duration::from_secs(10)); - let erc20_coin = erc20_coin_with_random_privkey(swap_contract()); + let erc20_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); erc20_coin.set_swap_transaction_fee_policy(swap_txfee_policy); let time_lock = now_sec() - 100; @@ -799,8 +845,8 @@ fn send_and_refund_erc20_maker_payment_priority_fee() { } fn send_and_spend_erc20_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { - let maker_erc20_coin = erc20_coin_with_random_privkey(swap_contract()); - let taker_erc20_coin = erc20_coin_with_random_privkey(swap_contract()); + let maker_erc20_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let taker_erc20_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); maker_erc20_coin.set_swap_transaction_fee_policy(swap_txfee_policy.clone()); taker_erc20_coin.set_swap_transaction_fee_policy(swap_txfee_policy); @@ -911,7 +957,15 @@ fn wait_pending_transactions(wallet_address: Address) { #[allow(dead_code)] fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option) -> EthCoin { match block_on(lp_coinfind(ctx, NFT_ETH)).unwrap() { - None => global_nft_from_privkey(ctx, sepolia_etomic_maker_nft(), priv_key, nft_type), + None => { + let swap_addresses = SwapAddressesWrapper { + swap_contract_address: swap_contract(), + maker_swap_v2_contract: maker_swap_v2(), + taker_swap_v2_contract: taker_swap_v2(), + nft_maker_swap_v2_contract: sepolia_etomic_maker_nft(), + }; + global_nft_from_privkey(ctx, swap_addresses, priv_key, nft_type) + }, Some(mm_coin) => match mm_coin { MmCoinEnum::EthCoin(nft) => nft, _ => panic!("Unexpected coin type found. Expected MmCoinEnum::EthCoin"), @@ -928,7 +982,7 @@ fn send_and_spend_erc721_maker_payment() { token_id, None, ContractType::Erc721, - geth_nft_maker_swap_v2(), + init_swap_contract_addresses(), geth_erc721_contract(), time_lock, ); @@ -964,7 +1018,7 @@ fn send_and_spend_erc1155_maker_payment() { token_id, Some(amount), ContractType::Erc1155, - geth_nft_maker_swap_v2(), + init_swap_contract_addresses(), geth_erc1155_contract(), time_lock, ); @@ -993,7 +1047,8 @@ fn send_and_spend_erc1155_maker_payment() { #[test] fn test_nonce_several_urls() { // Use one working and one failing URL. - let coin = eth_coin_with_random_privkey_using_urls(swap_contract(), &[GETH_RPC_URL, "http://127.0.0.1:0"]); + let coin = + eth_coin_with_random_privkey_using_urls(init_swap_contract_addresses(), &[GETH_RPC_URL, "http://127.0.0.1:0"]); let my_address = block_on(coin.derivation_method().single_addr_or_err()).unwrap(); let (old_nonce, _) = coin.clone().get_addr_nonce(my_address).wait().unwrap(); @@ -1008,7 +1063,7 @@ fn test_nonce_several_urls() { fn test_nonce_lock() { use futures::future::join_all; - let coin = eth_coin_with_random_privkey(swap_contract()); + let coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let my_address = block_on(coin.derivation_method().single_addr_or_err()).unwrap(); let futures = (0..5).map(|_| coin.send_to_address(my_address, 200000000.into()).compat()); let results = block_on(join_all(futures)); @@ -1028,7 +1083,7 @@ fn send_and_refund_erc721_maker_payment_timelock() { token_id, None, ContractType::Erc721, - geth_nft_maker_swap_v2(), + init_swap_contract_addresses(), geth_erc721_contract(), time_lock_to_refund, ); @@ -1070,7 +1125,7 @@ fn send_and_refund_erc1155_maker_payment_timelock() { token_id, Some(amount), ContractType::Erc1155, - geth_nft_maker_swap_v2(), + init_swap_contract_addresses(), geth_erc1155_contract(), time_lock_to_refund, ); @@ -1112,7 +1167,7 @@ fn send_and_refund_erc721_maker_payment_secret() { token_id, None, ContractType::Erc721, - geth_nft_maker_swap_v2(), + init_swap_contract_addresses(), geth_erc721_contract(), time_lock_to_refund, ); @@ -1155,7 +1210,7 @@ fn send_and_refund_erc1155_maker_payment_secret() { token_id, Some(amount), ContractType::Erc1155, - geth_nft_maker_swap_v2(), + init_swap_contract_addresses(), geth_erc1155_contract(), time_lock_to_refund, ); @@ -1214,7 +1269,7 @@ fn setup_test( token_id: u32, amount: Option, contract_type: ContractType, - nft_swap_contract: Address, + swap_addresses: SwapAddressesWrapper, token_contract: Address, time_lock: u64, ) -> NftTestSetup { @@ -1226,8 +1281,8 @@ fn setup_test( }, }; - let maker_global_nft = global_nft_with_random_privkey(nft_swap_contract, Some(nft_type)); - let taker_global_nft = global_nft_with_random_privkey(nft_swap_contract, None); + let maker_global_nft = global_nft_with_random_privkey(swap_addresses.clone(), Some(nft_type)); + let taker_global_nft = global_nft_with_random_privkey(swap_addresses.clone(), None); let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); let taker_secret = vec![0; 32]; @@ -1239,7 +1294,7 @@ fn setup_test( token_address: token_contract, token_id, contract_type, - swap_contract_address: nft_swap_contract, + swap_contract_address: swap_addresses.nft_maker_swap_v2_contract, }; NftTestSetup { diff --git a/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs b/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs index 98973aaf96..ecdd6a1704 100644 --- a/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs @@ -1,6 +1,7 @@ use crate::docker_tests::docker_tests_common::GETH_RPC_URL; use crate::docker_tests::eth_docker_tests::{erc20_coin_with_random_privkey, erc20_contract_checksum, - eth_coin_with_random_privkey, watchers_swap_contract}; + eth_coin_with_random_privkey, init_swap_contract_addresses, + watchers_swap_contract}; use crate::integration_tests_common::*; use crate::{generate_utxo_coin_with_privkey, generate_utxo_coin_with_random_privkey, random_secp256k1_secret}; use coins::coin_errors::ValidatePaymentError; @@ -763,9 +764,9 @@ fn test_watcher_spends_maker_payment_utxo_utxo() { #[test] fn test_watcher_spends_maker_payment_utxo_eth() { - let alice_coin = eth_coin_with_random_privkey(watchers_swap_contract()); - let bob_coin = eth_coin_with_random_privkey(watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let alice_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let bob_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let balances = start_swaps_and_get_balances( "ETH", @@ -792,9 +793,9 @@ fn test_watcher_spends_maker_payment_utxo_eth() { #[test] fn test_watcher_spends_maker_payment_eth_utxo() { - let alice_coin = eth_coin_with_random_privkey(watchers_swap_contract()); - let bob_coin = eth_coin_with_random_privkey(watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let alice_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let bob_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let balances = start_swaps_and_get_balances( "MYCOIN", @@ -834,9 +835,9 @@ fn test_watcher_spends_maker_payment_eth_utxo() { #[test] fn test_watcher_spends_maker_payment_eth_erc20() { - let alice_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); - let bob_coin = eth_coin_with_random_privkey(watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let bob_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let balances = start_swaps_and_get_balances( "ERC20DEV", @@ -867,9 +868,9 @@ fn test_watcher_spends_maker_payment_eth_erc20() { #[test] fn test_watcher_spends_maker_payment_erc20_eth() { - let alice_coin = eth_coin_with_random_privkey(watchers_swap_contract()); - let bob_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let alice_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let bob_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let balances = start_swaps_and_get_balances( "ETH", @@ -897,9 +898,9 @@ fn test_watcher_spends_maker_payment_erc20_eth() { #[test] fn test_watcher_spends_maker_payment_utxo_erc20() { - let alice_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); - let bob_coin = eth_coin_with_random_privkey(watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let bob_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let balances = start_swaps_and_get_balances( "ERC20DEV", @@ -930,9 +931,9 @@ fn test_watcher_spends_maker_payment_utxo_erc20() { #[test] fn test_watcher_spends_maker_payment_erc20_utxo() { - let alice_coin = eth_coin_with_random_privkey(watchers_swap_contract()); - let bob_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let alice_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let bob_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let balances = start_swaps_and_get_balances( "MYCOIN", @@ -1009,9 +1010,9 @@ fn test_watcher_refunds_taker_payment_utxo() { #[test] fn test_watcher_refunds_taker_payment_eth() { - let alice_coin = eth_coin_with_random_privkey(watchers_swap_contract()); - let bob_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let alice_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let bob_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let balances = start_swaps_and_get_balances( "ETH", @@ -1032,9 +1033,9 @@ fn test_watcher_refunds_taker_payment_eth() { #[test] fn test_watcher_refunds_taker_payment_erc20() { - let alice_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); - let bob_coin = eth_coin_with_random_privkey(watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let bob_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let balances = start_swaps_and_get_balances( "ERC20DEV", @@ -1087,9 +1088,9 @@ fn test_watcher_waits_for_taker_utxo() { #[test] fn test_watcher_waits_for_taker_eth() { - let alice_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); - let bob_coin = eth_coin_with_random_privkey(watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let bob_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); start_swaps_and_get_balances( "ERC20DEV", @@ -1328,7 +1329,7 @@ fn test_watcher_validate_taker_fee_eth() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run let lock_duration = get_payment_locktime(); - let taker_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let taker_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pubkey = taker_keypair.public(); @@ -1435,7 +1436,7 @@ fn test_watcher_validate_taker_fee_erc20() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run let lock_duration = get_payment_locktime(); - let taker_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); + let taker_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pubkey = taker_keypair.public(); @@ -1752,7 +1753,7 @@ fn test_watcher_validate_taker_payment_utxo() { fn test_watcher_validate_taker_payment_eth() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let taker_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); @@ -1995,7 +1996,7 @@ fn test_watcher_validate_taker_payment_eth() { fn test_watcher_validate_taker_payment_erc20() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); + let taker_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); @@ -2323,11 +2324,11 @@ fn test_taker_validates_taker_payment_refund_utxo() { fn test_taker_validates_taker_payment_refund_eth() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let taker_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); - let maker_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let maker_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let maker_keypair = maker_coin.derive_htlc_key_pair(&[]); let maker_pub = maker_keypair.public(); @@ -2644,7 +2645,7 @@ fn test_taker_validates_taker_payment_refund_eth() { fn test_taker_validates_taker_payment_refund_erc20() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); + let taker_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); @@ -2853,11 +2854,11 @@ fn test_taker_validates_maker_payment_spend_utxo() { fn test_taker_validates_maker_payment_spend_eth() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let taker_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); - let maker_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let maker_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let maker_keypair = maker_coin.derive_htlc_key_pair(&[]); let maker_pub = maker_keypair.public(); @@ -3183,11 +3184,11 @@ fn test_taker_validates_maker_payment_spend_eth() { fn test_taker_validates_maker_payment_spend_erc20() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); + let taker_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); - let maker_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); + let maker_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); let maker_keypair = maker_coin.derive_htlc_key_pair(&[]); let maker_pub = maker_keypair.public(); @@ -3389,7 +3390,7 @@ fn test_send_taker_payment_refund_preimage_utxo() { fn test_watcher_reward() { let timeout = wait_until_sec(300); // timeout if test takes more than 300 seconds to run let (_ctx, utxo_coin, _) = generate_utxo_coin_with_random_privkey("MYCOIN", 1000u64.into()); - let eth_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let eth_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); let watcher_reward = block_on(eth_coin.get_taker_watcher_reward(&MmCoinEnum::EthCoin(eth_coin.clone()), None, None, None, timeout)) diff --git a/mm2src/mm2_main/tests/mm2_tests/eth_tests.rs b/mm2src/mm2_main/tests/mm2_tests/eth_tests.rs index fc904a368f..ab754a8c4f 100644 --- a/mm2src/mm2_main/tests/mm2_tests/eth_tests.rs +++ b/mm2src/mm2_main/tests/mm2_tests/eth_tests.rs @@ -68,6 +68,8 @@ async fn enable_eth(mm: &MarketMakerIt, platform_coin: &str, nodes: &[&str]) -> "coin": platform_coin, "urls": nodes, "swap_contract_address": ETH_SEPOLIA_SWAP_CONTRACT, + "maker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, + "taker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, "mm2": 1, })) .await diff --git a/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs b/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs index 06abd46a92..5fc6622e89 100644 --- a/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs +++ b/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs @@ -3573,6 +3573,8 @@ fn test_get_raw_transaction() { "urls": &[ETH_MAINNET_NODE], // Dev chain swap contract address "swap_contract_address": ETH_MAINNET_SWAP_CONTRACT, + "maker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, + "taker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, "mm2": 1, }))) .unwrap(); @@ -6032,6 +6034,8 @@ mod trezor_tests { "coin": "ETH", "urls": ETH_SEPOLIA_NODES, "swap_contract_address": ETH_SEPOLIA_SWAP_CONTRACT, + "maker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, + "taker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, "priv_key_policy": "Trezor", }); @@ -6280,6 +6284,8 @@ mod trezor_tests { {"url": "https://rpc.sepolia.org/"} ], "swap_contract_address": ETH_SEPOLIA_SWAP_CONTRACT, + "maker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, + "taker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, "erc20_tokens_requests": [{"ticker": ticker_token}], "priv_key_policy": "Trezor" })) @@ -6398,6 +6404,8 @@ mod trezor_tests { {"url": ETH_SEPOLIA_NODES[0]} ], "swap_contract_address": ETH_SEPOLIA_SWAP_CONTRACT, + "maker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, + "taker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, "erc20_tokens_requests": [], "priv_key_policy": "Trezor" })) diff --git a/mm2src/mm2_test_helpers/src/for_tests.rs b/mm2src/mm2_test_helpers/src/for_tests.rs index ba0e2be593..ac24fe4350 100644 --- a/mm2src/mm2_test_helpers/src/for_tests.rs +++ b/mm2src/mm2_test_helpers/src/for_tests.rs @@ -1832,6 +1832,8 @@ pub async fn enable_qrc20( "servers": servers, "mm2": 1, "swap_contract_address": swap_contract_address, + "maker_swap_v2_contract": swap_contract_address, + "taker_swap_v2_contract": swap_contract_address, "path_to_address": path_to_address.unwrap_or_default(), })) .await @@ -1918,6 +1920,8 @@ pub async fn enable_native( "urls": urls, // Dev chain swap contract address "swap_contract_address": ETH_SEPOLIA_SWAP_CONTRACT, + "maker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, + "taker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, "path_to_address": path_to_address.unwrap_or_default(), "mm2": 1, })) @@ -1942,6 +1946,8 @@ pub async fn enable_eth_coin( "coin": coin, "urls": urls, "swap_contract_address": swap_contract_address, + "maker_swap_v2_contract": swap_contract_address, + "taker_swap_v2_contract": swap_contract_address, "fallback_swap_contract": fallback_swap_contract, "mm2": 1, "contract_supports_watchers": contract_supports_watcher @@ -3136,6 +3142,8 @@ pub async fn init_eth_with_tokens( "params": { "ticker": platform_coin, "swap_contract_address": swap_contract_address, + "maker_swap_v2_contract": swap_contract_address, + "taker_swap_v2_contract": swap_contract_address, "nodes": nodes, "tx_history": true, "erc20_tokens_requests": erc20_tokens_requests, @@ -3372,6 +3380,8 @@ pub async fn test_qrc20_history_impl(local_start: Option) { "mm2": 1, "tx_history": true, "swap_contract_address": "0xd362e096e873eb7907e205fadc6175c6fec7bc44", + "maker_swap_v2_contract": "0xd362e096e873eb7907e205fadc6175c6fec7bc44", + "taker_swap_v2_contract": "0xd362e096e873eb7907e205fadc6175c6fec7bc44", })) .await .unwrap(); From 9803fd537685a37d04f38506b6638d3bcc07610c Mon Sep 17 00:00:00 2001 From: laruh Date: Sat, 8 Jun 2024 13:16:11 +0700 Subject: [PATCH 056/233] eth tpu v2: dont include "nft_maker_swap_v2_contract" in eth/erc20 activation in tests --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 05c911caf8..579eaeb74f 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -283,7 +283,6 @@ pub fn eth_coin_with_random_privkey_using_urls(swap_addresses: SwapAddressesWrap "swap_contract_address": swap_addresses.swap_contract_address, "maker_swap_v2_contract": swap_addresses.maker_swap_v2_contract, "taker_swap_v2_contract": swap_addresses.taker_swap_v2_contract, - "nft_maker_swap_v2_contract": swap_addresses.nft_maker_swap_v2_contract, "urls": urls, }); @@ -340,7 +339,6 @@ pub fn erc20_coin_with_random_privkey(swap_addresses: SwapAddressesWrapper) -> E "swap_contract_address": swap_addresses.swap_contract_address, "maker_swap_v2_contract": swap_addresses.maker_swap_v2_contract, "taker_swap_v2_contract": swap_addresses.taker_swap_v2_contract, - "nft_maker_swap_v2_contract": swap_addresses.nft_maker_swap_v2_contract, "urls": [GETH_RPC_URL], }); @@ -545,7 +543,6 @@ pub fn fill_eth_erc20_with_private_key(priv_key: Secp256k1Secret) { "swap_contract_address": swap_contract(), "maker_swap_v2_contract": maker_swap_v2(), "taker_swap_v2_contract": taker_swap_v2(), - "nft_maker_swap_v2_contract": geth_nft_maker_swap_v2(), }); let eth_coin = block_on(eth_coin_from_conf_and_request( @@ -570,7 +567,6 @@ pub fn fill_eth_erc20_with_private_key(priv_key: Secp256k1Secret) { "swap_contract_address": swap_contract(), "maker_swap_v2_contract": maker_swap_v2(), "taker_swap_v2_contract": taker_swap_v2(), - "nft_maker_swap_v2_contract": geth_nft_maker_swap_v2(), }); let _erc20_coin = block_on(eth_coin_from_conf_and_request( From 2828be0312a801961bf822a13f0a589f240bd76f Mon Sep 17 00:00:00 2001 From: laruh Date: Sat, 8 Jun 2024 13:25:55 +0700 Subject: [PATCH 057/233] eth tpu v2: provide init_watchers_swap_contract in swap_watcher_tests.rs --- .../tests/docker_tests/eth_docker_tests.rs | 9 +++ .../tests/docker_tests/swap_watcher_tests.rs | 80 +++++++++---------- 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 579eaeb74f..2860084385 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -325,6 +325,15 @@ pub fn init_swap_contract_addresses() -> SwapAddressesWrapper { } } +pub fn init_watchers_swap_contract() -> SwapAddressesWrapper { + SwapAddressesWrapper { + swap_contract_address: watchers_swap_contract(), + maker_swap_v2_contract: maker_swap_v2(), + taker_swap_v2_contract: taker_swap_v2(), + nft_maker_swap_v2_contract: geth_nft_maker_swap_v2(), + } +} + /// Creates ETH protocol coin supplied with 100 ETH, using the default GETH_RPC_URL pub fn eth_coin_with_random_privkey(swap_addresses: SwapAddressesWrapper) -> EthCoin { eth_coin_with_random_privkey_using_urls(swap_addresses, &[GETH_RPC_URL]) diff --git a/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs b/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs index ecdd6a1704..3b43136cf6 100644 --- a/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs @@ -1,6 +1,6 @@ use crate::docker_tests::docker_tests_common::GETH_RPC_URL; use crate::docker_tests::eth_docker_tests::{erc20_coin_with_random_privkey, erc20_contract_checksum, - eth_coin_with_random_privkey, init_swap_contract_addresses, + eth_coin_with_random_privkey, init_watchers_swap_contract, watchers_swap_contract}; use crate::integration_tests_common::*; use crate::{generate_utxo_coin_with_privkey, generate_utxo_coin_with_random_privkey, random_secp256k1_secret}; @@ -764,9 +764,9 @@ fn test_watcher_spends_maker_payment_utxo_utxo() { #[test] fn test_watcher_spends_maker_payment_utxo_eth() { - let alice_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); - let bob_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); - let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let alice_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let bob_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); let balances = start_swaps_and_get_balances( "ETH", @@ -793,9 +793,9 @@ fn test_watcher_spends_maker_payment_utxo_eth() { #[test] fn test_watcher_spends_maker_payment_eth_utxo() { - let alice_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); - let bob_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); - let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let alice_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let bob_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); let balances = start_swaps_and_get_balances( "MYCOIN", @@ -835,9 +835,9 @@ fn test_watcher_spends_maker_payment_eth_utxo() { #[test] fn test_watcher_spends_maker_payment_eth_erc20() { - let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); - let bob_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); - let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let alice_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); + let bob_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); let balances = start_swaps_and_get_balances( "ERC20DEV", @@ -868,9 +868,9 @@ fn test_watcher_spends_maker_payment_eth_erc20() { #[test] fn test_watcher_spends_maker_payment_erc20_eth() { - let alice_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); - let bob_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); - let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let alice_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let bob_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); let balances = start_swaps_and_get_balances( "ETH", @@ -898,9 +898,9 @@ fn test_watcher_spends_maker_payment_erc20_eth() { #[test] fn test_watcher_spends_maker_payment_utxo_erc20() { - let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); - let bob_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); - let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let alice_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); + let bob_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); let balances = start_swaps_and_get_balances( "ERC20DEV", @@ -931,9 +931,9 @@ fn test_watcher_spends_maker_payment_utxo_erc20() { #[test] fn test_watcher_spends_maker_payment_erc20_utxo() { - let alice_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); - let bob_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); - let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let alice_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let bob_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); let balances = start_swaps_and_get_balances( "MYCOIN", @@ -1010,9 +1010,9 @@ fn test_watcher_refunds_taker_payment_utxo() { #[test] fn test_watcher_refunds_taker_payment_eth() { - let alice_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); - let bob_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); - let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let alice_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let bob_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); let balances = start_swaps_and_get_balances( "ETH", @@ -1033,9 +1033,9 @@ fn test_watcher_refunds_taker_payment_eth() { #[test] fn test_watcher_refunds_taker_payment_erc20() { - let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); - let bob_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); - let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let alice_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); + let bob_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); let balances = start_swaps_and_get_balances( "ERC20DEV", @@ -1088,9 +1088,9 @@ fn test_watcher_waits_for_taker_utxo() { #[test] fn test_watcher_waits_for_taker_eth() { - let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); - let bob_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); - let watcher_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let alice_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); + let bob_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); start_swaps_and_get_balances( "ERC20DEV", @@ -1329,7 +1329,7 @@ fn test_watcher_validate_taker_fee_eth() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run let lock_duration = get_payment_locktime(); - let taker_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let taker_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pubkey = taker_keypair.public(); @@ -1436,7 +1436,7 @@ fn test_watcher_validate_taker_fee_erc20() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run let lock_duration = get_payment_locktime(); - let taker_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let taker_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pubkey = taker_keypair.public(); @@ -1753,7 +1753,7 @@ fn test_watcher_validate_taker_payment_utxo() { fn test_watcher_validate_taker_payment_eth() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let taker_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); @@ -1996,7 +1996,7 @@ fn test_watcher_validate_taker_payment_eth() { fn test_watcher_validate_taker_payment_erc20() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let taker_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); @@ -2324,11 +2324,11 @@ fn test_taker_validates_taker_payment_refund_utxo() { fn test_taker_validates_taker_payment_refund_eth() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let taker_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); - let maker_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let maker_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); let maker_keypair = maker_coin.derive_htlc_key_pair(&[]); let maker_pub = maker_keypair.public(); @@ -2645,7 +2645,7 @@ fn test_taker_validates_taker_payment_refund_eth() { fn test_taker_validates_taker_payment_refund_erc20() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let taker_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); @@ -2854,11 +2854,11 @@ fn test_taker_validates_maker_payment_spend_utxo() { fn test_taker_validates_maker_payment_spend_eth() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let taker_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); - let maker_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let maker_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); let maker_keypair = maker_coin.derive_htlc_key_pair(&[]); let maker_pub = maker_keypair.public(); @@ -3184,11 +3184,11 @@ fn test_taker_validates_maker_payment_spend_eth() { fn test_taker_validates_maker_payment_spend_erc20() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let taker_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); - let maker_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let maker_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); let maker_keypair = maker_coin.derive_htlc_key_pair(&[]); let maker_pub = maker_keypair.public(); @@ -3390,7 +3390,7 @@ fn test_send_taker_payment_refund_preimage_utxo() { fn test_watcher_reward() { let timeout = wait_until_sec(300); // timeout if test takes more than 300 seconds to run let (_ctx, utxo_coin, _) = generate_utxo_coin_with_random_privkey("MYCOIN", 1000u64.into()); - let eth_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let eth_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); let watcher_reward = block_on(eth_coin.get_taker_watcher_reward(&MmCoinEnum::EthCoin(eth_coin.clone()), None, None, None, timeout)) From 04d99e4b03ec1aabafc2c05c93c501c3c7297d66 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 10 Jun 2024 15:55:30 +0700 Subject: [PATCH 058/233] eth tpu v2: impl TakerCoinSwapOpsV2 for EthCoin, send_taker_funding WIP --- mm2src/coins/eth.rs | 98 +++++++++++++++++++ mm2src/coins/eth/eth_swap_v2.rs | 17 ++++ mm2src/coins/lp_coins.rs | 14 ++- mm2src/coins/utxo/utxo_common.rs | 2 +- mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 4 +- .../tests/docker_tests/swap_proto_v2_tests.rs | 32 +++--- 6 files changed, 149 insertions(+), 18 deletions(-) create mode 100644 mm2src/coins/eth/eth_swap_v2.rs diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 82fb3a57cd..1cb945c601 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -159,6 +159,7 @@ mod eip1559_gas_fee; pub(crate) use eip1559_gas_fee::FeePerGasEstimated; use eip1559_gas_fee::{BlocknativeGasApiCaller, FeePerGasSimpleEstimator, GasApiConfig, GasApiProvider, InfuraGasApiCaller}; +mod eth_swap_v2; /// https://github.com/artemii235/etomic-swap/blob/master/contracts/EtomicSwap.sol /// Dev chain (195.201.137.5:8565) contract address: 0x83965C539899cC0F918552e5A26915de40ee8852 @@ -7048,3 +7049,100 @@ impl Eip1559Ops for EthCoin { *self.swap_txfee_policy.lock().unwrap() = swap_txfee_policy } } + +#[async_trait] +impl TakerCoinSwapOpsV2 for EthCoin { + async fn send_taker_funding(&self, args: SendTakerFundingArgs<'_>) -> Result { + self.send_taker_funding_impl(args).await + } + + async fn validate_taker_funding(&self, _args: ValidateTakerFundingArgs<'_, Self>) -> ValidateSwapV2TxResult { + todo!() + } + + async fn refund_taker_funding_timelock(&self, _args: RefundPaymentArgs<'_>) -> Result { + todo!() + } + + async fn refund_taker_funding_secret( + &self, + _args: RefundFundingSecretArgs<'_, Self>, + ) -> Result { + todo!() + } + + async fn search_for_taker_funding_spend( + &self, + _tx: &Self::Tx, + _from_block: u64, + _secret_hash: &[u8], + ) -> Result>, SearchForFundingSpendErr> { + todo!() + } + + async fn gen_taker_funding_spend_preimage( + &self, + _args: &GenTakerFundingSpendArgs<'_, Self>, + _swap_unique_data: &[u8], + ) -> GenPreimageResult { + todo!() + } + + async fn validate_taker_funding_spend_preimage( + &self, + _gen_args: &GenTakerFundingSpendArgs<'_, Self>, + _preimage: &TxPreimageWithSig, + ) -> ValidateTakerFundingSpendPreimageResult { + todo!() + } + + async fn sign_and_send_taker_funding_spend( + &self, + _preimage: &TxPreimageWithSig, + _args: &GenTakerFundingSpendArgs<'_, Self>, + _swap_unique_data: &[u8], + ) -> Result { + todo!() + } + + async fn refund_combined_taker_payment(&self, _args: RefundPaymentArgs<'_>) -> Result { + todo!() + } + + async fn gen_taker_payment_spend_preimage( + &self, + _args: &GenTakerPaymentSpendArgs<'_, Self>, + _swap_unique_data: &[u8], + ) -> GenPreimageResult { + todo!() + } + + async fn validate_taker_payment_spend_preimage( + &self, + _gen_args: &GenTakerPaymentSpendArgs<'_, Self>, + _preimage: &TxPreimageWithSig, + ) -> ValidateTakerPaymentSpendPreimageResult { + todo!() + } + + async fn sign_and_broadcast_taker_payment_spend( + &self, + _preimage: &TxPreimageWithSig, + _gen_args: &GenTakerPaymentSpendArgs<'_, Self>, + _secret: &[u8], + _swap_unique_data: &[u8], + ) -> Result { + todo!() + } + + async fn wait_for_taker_payment_spend( + &self, + _taker_payment: &Self::Tx, + _from_block: u64, + _wait_until: u64, + ) -> MmResult { + todo!() + } + + fn derive_htlc_pubkey_v2(&self, _swap_unique_data: &[u8]) -> Self::Pubkey { todo!() } +} diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs new file mode 100644 index 0000000000..4cc85074f1 --- /dev/null +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -0,0 +1,17 @@ +use crate::eth::{wei_from_big_decimal, EthCoin, SignedEthTx}; +use crate::{SendTakerFundingArgs, TransactionErr}; + +impl EthCoin { + pub(crate) async fn send_taker_funding_impl( + &self, + args: SendTakerFundingArgs<'_>, + ) -> Result { + let _dex_fee = try_tx_s!(wei_from_big_decimal(&args.dex_fee.fee_amount().into(), self.decimals)); + + let _payment_amount = try_tx_s!(wei_from_big_decimal( + &(args.trading_amount + args.premium_amount), + self.decimals + )); + todo!() + } +} diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 3f147b8ac2..b4ddcf2105 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1251,17 +1251,21 @@ pub trait WatcherOps { /// Helper struct wrapping arguments for [TakerCoinSwapOpsV2::send_taker_funding] pub struct SendTakerFundingArgs<'a> { - /// Taker will be able to refund the payment after this timestamp - pub time_lock: u64, - /// The hash of the secret generated by taker, this needs to be revealed for immediate refund + /// The timestamp after which the taker can refund the funding transaction if the maker hasn't pre-approved the transaction + pub funding_time_lock: u64, + /// The timestamp after which the taker can refund the payment transaction if the maker hasn't claimed it by revealing their secret + pub payment_time_lock: u64, + /// The hash of the secret generated by the taker, needed to reveal for immediate refund pub taker_secret_hash: &'a [u8], + /// The hash of the secret generated by the maker, needed to reveal to spend the payment + pub maker_secret_hash: &'a [u8], /// Maker's pubkey pub maker_pub: &'a [u8], /// DEX fee pub dex_fee: &'a DexFee, - /// Additional reward for maker (premium) + /// Additional reward for the maker (premium) pub premium_amount: BigDecimal, - /// Actual volume of taker's payment + /// Actual volume of the taker's payment pub trading_amount: BigDecimal, /// Unique data of specific swap pub swap_unique_data: &'a [u8], diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index be54d53fe1..7960fd3fd1 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -4795,7 +4795,7 @@ where outputs, } = try_tx_s!(generate_swap_payment_outputs( &coin, - try_tx_s!(args.time_lock.try_into()), + try_tx_s!(args.funding_time_lock.try_into()), taker_htlc_key_pair.public_slice(), args.maker_pub, total_amount, diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs index 256503350b..3226c46b2f 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs @@ -1221,8 +1221,10 @@ impl, state_machine: &mut Self::StateMachine) -> StateResult { let args = SendTakerFundingArgs { - time_lock: state_machine.taker_funding_locktime(), + funding_time_lock: state_machine.taker_funding_locktime(), + payment_time_lock: state_machine.taker_payment_locktime(), taker_secret_hash: &state_machine.taker_secret_hash(), + maker_secret_hash: &self.negotiation_data.maker_secret_hash, maker_pub: &self.negotiation_data.taker_coin_htlc_pub_from_maker.to_bytes(), dex_fee: &state_machine.dex_fee, premium_amount: state_machine.taker_premium.to_decimal(), diff --git a/mm2src/mm2_main/tests/docker_tests/swap_proto_v2_tests.rs b/mm2src/mm2_main/tests/docker_tests/swap_proto_v2_tests.rs index a090f64a50..eb570f680a 100644 --- a/mm2src/mm2_main/tests/docker_tests/swap_proto_v2_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/swap_proto_v2_tests.rs @@ -22,14 +22,16 @@ use uuid::Uuid; fn send_and_refund_taker_funding_timelock() { let (_mm_arc, coin, _privkey) = generate_utxo_coin_with_random_privkey(MYCOIN, 1000.into()); - let time_lock = now_sec() - 1000; + let funding_time_lock = now_sec() - 1000; let taker_secret_hash = &[0; 20]; let maker_pub = coin.my_public_key().unwrap(); let dex_fee = &DexFee::Standard("0.01".into()); let send_args = SendTakerFundingArgs { - time_lock, + funding_time_lock, + payment_time_lock: 0, taker_secret_hash, + maker_secret_hash: &[0; 20], maker_pub, dex_fee, premium_amount: "0.1".parse().unwrap(), @@ -53,7 +55,7 @@ fn send_and_refund_taker_funding_timelock() { let validate_args = ValidateTakerFundingArgs { funding_tx: &taker_funding_utxo_tx, - time_lock, + time_lock: funding_time_lock, taker_secret_hash, other_pub: maker_pub, dex_fee, @@ -65,7 +67,7 @@ fn send_and_refund_taker_funding_timelock() { let refund_args = RefundPaymentArgs { payment_tx: &serialize(&taker_funding_utxo_tx).take(), - time_lock, + time_lock: funding_time_lock, other_pubkey: coin.my_public_key().unwrap(), tx_type_with_secret_hash: SwapTxTypeWithSecretHash::TakerFunding { taker_secret_hash: &[0; 20], @@ -100,7 +102,7 @@ fn send_and_refund_taker_funding_timelock() { fn send_and_refund_taker_funding_secret() { let (_mm_arc, coin, _privkey) = generate_utxo_coin_with_random_privkey(MYCOIN, 1000.into()); - let time_lock = now_sec() - 1000; + let funding_time_lock = now_sec() - 1000; let taker_secret = [0; 32]; let taker_secret_hash_owned = dhash160(&taker_secret); let taker_secret_hash = taker_secret_hash_owned.as_slice(); @@ -108,8 +110,10 @@ fn send_and_refund_taker_funding_secret() { let dex_fee = &DexFee::Standard("0.01".into()); let send_args = SendTakerFundingArgs { - time_lock, + funding_time_lock, + payment_time_lock: 0, taker_secret_hash, + maker_secret_hash: &[0; 20], maker_pub, dex_fee, premium_amount: "0.1".parse().unwrap(), @@ -133,7 +137,7 @@ fn send_and_refund_taker_funding_secret() { let validate_args = ValidateTakerFundingArgs { funding_tx: &taker_funding_utxo_tx, - time_lock, + time_lock: funding_time_lock, taker_secret_hash, other_pub: maker_pub, dex_fee, @@ -145,7 +149,7 @@ fn send_and_refund_taker_funding_secret() { let refund_args = RefundFundingSecretArgs { funding_tx: &taker_funding_utxo_tx, - time_lock, + time_lock: funding_time_lock, maker_pubkey: maker_pub, taker_secret: &taker_secret, taker_secret_hash, @@ -192,8 +196,10 @@ fn send_and_spend_taker_funding() { let dex_fee = &DexFee::Standard("0.01".into()); let send_args = SendTakerFundingArgs { - time_lock: funding_time_lock, + funding_time_lock, + payment_time_lock: 0, taker_secret_hash, + maker_secret_hash: &[0; 20], maker_pub, dex_fee, premium_amount: "0.1".parse().unwrap(), @@ -279,8 +285,10 @@ fn send_and_spend_taker_payment_dex_fee_burn() { let dex_fee = &DexFee::with_burn("0.75".into(), "0.25".into()); let send_args = SendTakerFundingArgs { - time_lock: funding_time_lock, + funding_time_lock, + payment_time_lock: 0, taker_secret_hash, + maker_secret_hash, maker_pub, dex_fee, premium_amount: 0.into(), @@ -382,8 +390,10 @@ fn send_and_spend_taker_payment_standard_dex_fee() { let dex_fee = &DexFee::Standard(1.into()); let send_args = SendTakerFundingArgs { - time_lock: funding_time_lock, + funding_time_lock, + payment_time_lock: 0, taker_secret_hash, + maker_secret_hash, maker_pub, dex_fee, premium_amount: 0.into(), From d31566d9038ba16e9d167c0f6c7c318a986af86d Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 10 Jun 2024 16:26:18 +0700 Subject: [PATCH 059/233] eth_docker_tests.rs change sleep Duration in some tests --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 2860084385..d38f3411d0 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -596,6 +596,7 @@ pub fn fill_eth_erc20_with_private_key(priv_key: Secp256k1Secret) { } fn send_and_refund_eth_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { + thread::sleep(Duration::from_secs(3)); let eth_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); eth_coin.set_swap_transaction_fee_policy(swap_txfee_policy); @@ -850,6 +851,7 @@ fn send_and_refund_erc20_maker_payment_priority_fee() { } fn send_and_spend_erc20_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { + thread::sleep(Duration::from_secs(1)); let maker_erc20_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); let taker_erc20_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); @@ -1081,7 +1083,7 @@ fn test_nonce_lock() { #[test] fn send_and_refund_erc721_maker_payment_timelock() { - thread::sleep(Duration::from_secs(10)); + thread::sleep(Duration::from_secs(25)); let token_id = 2u32; let time_lock_to_refund = now_sec() - 1000; let setup = setup_test( @@ -1122,7 +1124,7 @@ fn send_and_refund_erc721_maker_payment_timelock() { #[test] fn send_and_refund_erc1155_maker_payment_timelock() { - thread::sleep(Duration::from_secs(10)); + thread::sleep(Duration::from_secs(20)); let token_id = 2u32; let amount = 3u32; let time_lock_to_refund = now_sec() - 1000; @@ -1141,7 +1143,7 @@ fn send_and_refund_erc1155_maker_payment_timelock() { maker_payment_to_refund.tx_hash() ); - wait_for_confirmations(&setup.maker_global_nft, &maker_payment_to_refund, 100); + wait_for_confirmations(&setup.maker_global_nft, &maker_payment_to_refund, 150); let balance = geth_erc1155_balance(geth_nft_maker_swap_v2(), U256::from(token_id)); assert_eq!(U256::from(amount), balance); @@ -1156,7 +1158,7 @@ fn send_and_refund_erc1155_maker_payment_timelock() { refund_timelock_tx.tx_hash() ); - wait_for_confirmations(&setup.maker_global_nft, &refund_timelock_tx, 100); + wait_for_confirmations(&setup.maker_global_nft, &refund_timelock_tx, 150); let maker_address = block_on(setup.maker_global_nft.my_addr()); let balance = geth_erc1155_balance(maker_address, U256::from(token_id)); assert_eq!(U256::from(amount), balance); From 40649999a7644f41b4b7b2924a3b9613051c829a Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 14 Jun 2024 11:05:33 +0700 Subject: [PATCH 060/233] eth tpu v2: impl TakerCoinSwapOpsV2 for EthCoin WIP --- mm2src/coins/eth.rs | 19 +++++ mm2src/coins/eth/eth_swap_v2.rs | 83 ++++++++++++++++++- mm2src/coins/lp_coins.rs | 10 ++- mm2src/coins/utxo/utxo_common.rs | 2 +- mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 7 +- .../tests/docker_tests/swap_proto_v2_tests.rs | 9 +- 6 files changed, 121 insertions(+), 9 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 1cb945c601..db539429e8 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -792,6 +792,25 @@ impl EthCoinImpl { sha256(&input).to_vec() } + /// The id used to differentiate payments on Etomic swap smart contract. + /// For Taker Etomic Swap contract taker_secret_hash should be provided. + pub(crate) fn etomic_swap_v2_id( + &self, + funding_time_lock: u32, + payment_time_lock: u32, + secret_hash: &[u8], + ) -> Vec { + let funding_timelock_bytes = funding_time_lock.to_le_bytes(); + let payment_timelock_bytes = payment_time_lock.to_le_bytes(); + + let mut input = + Vec::with_capacity(funding_timelock_bytes.len() + payment_timelock_bytes.len() + secret_hash.len()); + input.extend_from_slice(&funding_timelock_bytes); + input.extend_from_slice(&payment_timelock_bytes); + input.extend_from_slice(secret_hash); + sha256(&input).to_vec() + } + /// Try to parse address from string. pub fn address_from_str(&self, address: &str) -> Result { Ok(try_s!(valid_addr_from_str(address))) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 4cc85074f1..d0a2a24b35 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,17 +1,92 @@ -use crate::eth::{wei_from_big_decimal, EthCoin, SignedEthTx}; +use crate::eth::{addr_from_raw_pubkey, gas_limit, wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, + TAKER_SWAP_V2}; use crate::{SendTakerFundingArgs, TransactionErr}; +use enum_derives::EnumFromStringify; +use ethabi::Token; +use ethcore_transaction::Action; +use ethereum_types::{Address, U256}; +use futures::compat::Future01CompatExt; +use std::convert::TryInto; + +#[allow(dead_code)] +struct TakerFundingArgs<'a> { + dex_fee: U256, + payment_amount: U256, + maker_address: Address, + taker_secret_hash: &'a [u8], + maker_secret_hash: &'a [u8], + funding_time_lock: u32, + payment_time_lock: u32, +} impl EthCoin { pub(crate) async fn send_taker_funding_impl( &self, args: SendTakerFundingArgs<'_>, ) -> Result { - let _dex_fee = try_tx_s!(wei_from_big_decimal(&args.dex_fee.fee_amount().into(), self.decimals)); + let dex_fee = try_tx_s!(wei_from_big_decimal(&args.dex_fee.fee_amount().into(), self.decimals)); - let _payment_amount = try_tx_s!(wei_from_big_decimal( + let payment_amount = try_tx_s!(wei_from_big_decimal( &(args.trading_amount + args.premium_amount), self.decimals )); - todo!() + let maker_address = try_tx_s!(addr_from_raw_pubkey(args.maker_pub)); + + let funding_time_lock: u32 = try_tx_s!(args.funding_time_lock.try_into()); + let payment_time_lock: u32 = try_tx_s!(args.payment_time_lock.try_into()); + let funding_args = TakerFundingArgs { + dex_fee, + payment_amount, + maker_address, + taker_secret_hash: args.taker_secret_hash, + maker_secret_hash: args.maker_secret_hash, + funding_time_lock, + payment_time_lock, + }; + + match &self.coin_type { + EthCoinType::Eth => { + let data = try_tx_s!(self.prepare_taker_eth_funding_data(&funding_args).await); + self.sign_and_send_transaction( + payment_amount, + Action::Call(self.taker_swap_v2_contract), + data, + U256::from(gas_limit::ETH_PAYMENT), + ) + .compat() + .await + }, + EthCoinType::Erc20 { .. } => { + todo!() + }, + EthCoinType::Nft { .. } => Err(TransactionErr::ProtocolNotSupported( + "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), + )), + } } + + async fn prepare_taker_eth_funding_data(&self, args: &TakerFundingArgs<'_>) -> Result, PrepareTxDataError> { + let function = TAKER_SWAP_V2.function("ethTakerPayment")?; + let id = self.etomic_swap_v2_id(args.funding_time_lock, args.payment_time_lock, args.taker_secret_hash); + let data = function.encode_input(&[ + Token::FixedBytes(id), + Token::Uint(args.dex_fee), + Token::Address(args.maker_address), + Token::FixedBytes(args.taker_secret_hash.to_vec()), + Token::FixedBytes(args.maker_secret_hash.to_vec()), + Token::Uint(args.funding_time_lock.into()), + Token::Uint(args.payment_time_lock.into()), + ])?; + Ok(data) + } +} + +#[allow(dead_code)] +#[derive(Debug, Display, EnumFromStringify)] +enum PrepareTxDataError { + #[from_stringify("ethabi::Error")] + #[display(fmt = "Abi error: {}", _0)] + AbiError(String), + #[display(fmt = "Internal error: {}", _0)] + Internal(String), } diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index b4ddcf2105..b218458c8e 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1274,11 +1274,19 @@ pub struct SendTakerFundingArgs<'a> { /// Helper struct wrapping arguments for [TakerCoinSwapOpsV2::refund_taker_funding_secret] pub struct RefundFundingSecretArgs<'a, Coin: ParseCoinAssocTypes + ?Sized> { pub funding_tx: &'a Coin::Tx, - pub time_lock: u64, + pub funding_time_lock: u64, + pub payment_time_lock: u64, pub maker_pubkey: &'a Coin::Pubkey, pub taker_secret: &'a [u8], pub taker_secret_hash: &'a [u8], + pub maker_secret_hash: &'a [u8], pub swap_contract_address: &'a Option, + /// DEX fee + pub dex_fee: &'a DexFee, + /// Additional reward for maker (premium) + pub premium_amount: BigDecimal, + /// Actual volume of taker's payment + pub trading_amount: BigDecimal, pub swap_unique_data: &'a [u8], pub watcher_reward: bool, } diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 7960fd3fd1..12c18f602c 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -4831,7 +4831,7 @@ where .push_opcode(Opcode::OP_0) .push_opcode(Opcode::OP_0) .into_script(); - let time_lock = try_tx_s!(args.time_lock.try_into()); + let time_lock = try_tx_s!(args.funding_time_lock.try_into()); let redeem_script = swap_proto_v2_scripts::taker_funding_script( time_lock, diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs index 3226c46b2f..f91e98f2f6 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs @@ -1793,11 +1793,16 @@ impl Date: Mon, 17 Jun 2024 13:39:08 +0700 Subject: [PATCH 061/233] avoid code duplication in input_tokens vector --- mm2src/coins/eth/nft_swap_v2/mod.rs | 98 ++++++++++++----------------- 1 file changed, 39 insertions(+), 59 deletions(-) diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index 30788634b0..c60c5304d4 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -342,26 +342,19 @@ impl EthCoin { ContractType::Erc1155 => NFT_MAKER_SWAP_V2.function("spendErc1155MakerPayment")?, ContractType::Erc721 => NFT_MAKER_SWAP_V2.function("spendErc721MakerPayment")?, }; - - let input_tokens = match args.contract_type { - ContractType::Erc1155 => vec![ - htlc_params[0].clone(), // swapId - Token::Address(args.maker_payment_tx.sender()), - Token::FixedBytes(args.taker_secret_hash.to_vec()), - Token::FixedBytes(args.maker_secret.to_vec()), - htlc_params[2].clone(), // tokenAddress - decoded[2].clone(), // tokenId - decoded[3].clone(), // amount - ], - ContractType::Erc721 => vec![ - htlc_params[0].clone(), // swap_id - Token::Address(args.maker_payment_tx.sender()), - Token::FixedBytes(args.taker_secret_hash.to_vec()), - Token::FixedBytes(args.maker_secret.to_vec()), - htlc_params[2].clone(), // tokenAddress - decoded[2].clone(), // tokenId - ], - }; + // Initialize tokens with common elements + let mut input_tokens = vec![ + htlc_params[0].clone(), // swapId + Token::Address(args.maker_payment_tx.sender()), + Token::FixedBytes(args.taker_secret_hash.to_vec()), + Token::FixedBytes(args.maker_secret.to_vec()), + htlc_params[2].clone(), // tokenAddress + decoded[2].clone(), // tokenId + ]; + // Add specific elements based on contract type + if let ContractType::Erc1155 = args.contract_type { + input_tokens.push(decoded[3].clone()); // amount + } let data = spend_func.encode_input(&input_tokens)?; Ok(data) @@ -380,26 +373,20 @@ impl EthCoin { ContractType::Erc1155 => NFT_MAKER_SWAP_V2.function("refundErc1155MakerPaymentTimelock")?, ContractType::Erc721 => NFT_MAKER_SWAP_V2.function("refundErc721MakerPaymentTimelock")?, }; + // Initialize tokens with common elements + let mut input_tokens = vec![ + htlc_params[0].clone(), // swapId + htlc_params[1].clone(), // takerAddress + Token::FixedBytes(args.taker_secret_hash.to_vec()), + Token::FixedBytes(args.maker_secret_hash.to_vec()), + htlc_params[2].clone(), // tokenAddress + decoded[2].clone(), // tokenId + ]; + // Add specific elements based on contract type + if let ContractType::Erc1155 = args.contract_type { + input_tokens.push(decoded[3].clone()); // amount + } - let input_tokens = match args.contract_type { - ContractType::Erc1155 => vec![ - htlc_params[0].clone(), // swapId - htlc_params[1].clone(), // takerAddress - Token::FixedBytes(args.taker_secret_hash.to_vec()), - Token::FixedBytes(args.maker_secret_hash.to_vec()), - htlc_params[2].clone(), // tokenAddress - decoded[2].clone(), // tokenId - decoded[3].clone(), // amount - ], - ContractType::Erc721 => vec![ - htlc_params[0].clone(), // swapId - htlc_params[1].clone(), // takerAddress - Token::FixedBytes(args.taker_secret_hash.to_vec()), - Token::FixedBytes(args.maker_secret_hash.to_vec()), - htlc_params[2].clone(), // tokenAddress - decoded[2].clone(), // tokenId - ], - }; let data = refund_func.encode_input(&input_tokens)?; Ok(data) } @@ -417,26 +404,19 @@ impl EthCoin { ContractType::Erc1155 => NFT_MAKER_SWAP_V2.function("refundErc1155MakerPaymentSecret")?, ContractType::Erc721 => NFT_MAKER_SWAP_V2.function("refundErc721MakerPaymentSecret")?, }; - - let input_tokens = match args.contract_type { - ContractType::Erc1155 => vec![ - htlc_params[0].clone(), // swapId - htlc_params[1].clone(), // takerAddress - Token::FixedBytes(args.taker_secret.to_vec()), - Token::FixedBytes(args.maker_secret_hash.to_vec()), - htlc_params[2].clone(), // tokenAddress - decoded[2].clone(), // tokenId - decoded[3].clone(), // amount - ], - ContractType::Erc721 => vec![ - htlc_params[0].clone(), // swapId - htlc_params[1].clone(), // takerAddress - Token::FixedBytes(args.taker_secret.to_vec()), - Token::FixedBytes(args.maker_secret_hash.to_vec()), - htlc_params[2].clone(), // tokenAddress - decoded[2].clone(), // tokenId - ], - }; + // Initialize tokens with common elements + let mut input_tokens = vec![ + htlc_params[0].clone(), // swapId + htlc_params[1].clone(), // takerAddress + Token::FixedBytes(args.taker_secret.to_vec()), + Token::FixedBytes(args.maker_secret_hash.to_vec()), + htlc_params[2].clone(), // tokenAddress + decoded[2].clone(), // tokenId + ]; + // Add specific elements based on contract type + if let ContractType::Erc1155 = args.contract_type { + input_tokens.push(decoded[3].clone()); // amount + } let data = refund_func.encode_input(&input_tokens)?; Ok(data) } From 40ffb653942419305cfa95eeb71441faed3773d4 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 17 Jun 2024 14:24:14 +0700 Subject: [PATCH 062/233] review: rename validate_state fnc, use extend plus chain in etomic_swap_v2_id fnc --- mm2src/coins/eth.rs | 9 ++++++--- mm2src/coins/eth/nft_swap_v2/mod.rs | 8 ++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index db539429e8..40a05f02f4 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -805,9 +805,12 @@ impl EthCoinImpl { let mut input = Vec::with_capacity(funding_timelock_bytes.len() + payment_timelock_bytes.len() + secret_hash.len()); - input.extend_from_slice(&funding_timelock_bytes); - input.extend_from_slice(&payment_timelock_bytes); - input.extend_from_slice(secret_hash); + input.extend( + funding_timelock_bytes + .iter() + .chain(payment_timelock_bytes.iter()) + .chain(secret_hash.iter()), + ); sha256(&input).to_vec() } diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index c60c5304d4..74976662ec 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -336,7 +336,7 @@ impl EthCoin { htlc_params: Vec, state: U256, ) -> Result, PrepareTxDataError> { - validate_state(args.maker_payment_tx, state, MakerPaymentStateV2::PaymentSent as u8)?; + validate_payment_state(args.maker_payment_tx, state, MakerPaymentStateV2::PaymentSent as u8)?; let spend_func = match args.contract_type { ContractType::Erc1155 => NFT_MAKER_SWAP_V2.function("spendErc1155MakerPayment")?, @@ -367,7 +367,7 @@ impl EthCoin { htlc_params: Vec, state: U256, ) -> Result, PrepareTxDataError> { - validate_state(args.maker_payment_tx, state, MakerPaymentStateV2::PaymentSent as u8)?; + validate_payment_state(args.maker_payment_tx, state, MakerPaymentStateV2::PaymentSent as u8)?; let refund_func = match args.contract_type { ContractType::Erc1155 => NFT_MAKER_SWAP_V2.function("refundErc1155MakerPaymentTimelock")?, @@ -398,7 +398,7 @@ impl EthCoin { htlc_params: Vec, state: U256, ) -> Result, PrepareTxDataError> { - validate_state(args.maker_payment_tx, state, MakerPaymentStateV2::PaymentSent as u8)?; + validate_payment_state(args.maker_payment_tx, state, MakerPaymentStateV2::PaymentSent as u8)?; let refund_func = match args.contract_type { ContractType::Erc1155 => NFT_MAKER_SWAP_V2.function("refundErc1155MakerPaymentSecret")?, @@ -656,7 +656,7 @@ fn erc721_transfer_with_data<'a>() -> Result<&'a ethabi::Function, Erc721Functio Ok(function) } -fn validate_state(tx: &SignedEthTx, state: U256, expected_state: u8) -> Result<(), PrepareTxDataError> { +fn validate_payment_state(tx: &SignedEthTx, state: U256, expected_state: u8) -> Result<(), PrepareTxDataError> { if state != U256::from(expected_state) { return Err(PrepareTxDataError::Internal(ERRL!( "Payment {:?} state is not {}, got {}", From 888108ca43530391e6b02dae561407bca01f52c5 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 18 Jun 2024 10:32:17 +0700 Subject: [PATCH 063/233] review: move contract bytes strings to txt files, remove "the" --- mm2src/coins/lp_coins.rs | 4 ++-- .../tests/docker_tests/docker_tests_common.rs | 23 +++++++++++-------- .../contract_bytes/erc1155_test_token_bytes | 1 + .../contract_bytes/erc20_token_bytes | 1 + .../contract_bytes/erc721_test_token_bytes | 1 + .../contract_bytes/maker_swap_v2_bytes | 1 + .../contract_bytes/nft_maker_swap_v2_bytes | 1 + .../contract_bytes/nft_swap_contract_bytes | 1 + .../contract_bytes/swap_contract_bytes | 1 + .../contract_bytes/taker_swap_v2_bytes | 1 + .../watchers_swap_contract_bytes | 1 + 11 files changed, 25 insertions(+), 11 deletions(-) create mode 100644 mm2src/mm2_test_helpers/contract_bytes/erc1155_test_token_bytes create mode 100644 mm2src/mm2_test_helpers/contract_bytes/erc20_token_bytes create mode 100644 mm2src/mm2_test_helpers/contract_bytes/erc721_test_token_bytes create mode 100644 mm2src/mm2_test_helpers/contract_bytes/maker_swap_v2_bytes create mode 100644 mm2src/mm2_test_helpers/contract_bytes/nft_maker_swap_v2_bytes create mode 100644 mm2src/mm2_test_helpers/contract_bytes/nft_swap_contract_bytes create mode 100644 mm2src/mm2_test_helpers/contract_bytes/swap_contract_bytes create mode 100644 mm2src/mm2_test_helpers/contract_bytes/taker_swap_v2_bytes create mode 100644 mm2src/mm2_test_helpers/contract_bytes/watchers_swap_contract_bytes diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index b218458c8e..1afb0d21ad 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1263,9 +1263,9 @@ pub struct SendTakerFundingArgs<'a> { pub maker_pub: &'a [u8], /// DEX fee pub dex_fee: &'a DexFee, - /// Additional reward for the maker (premium) + /// Additional reward for maker (premium) pub premium_amount: BigDecimal, - /// Actual volume of the taker's payment + /// Actual volume of taker's payment pub trading_amount: BigDecimal, /// Unique data of specific swap pub swap_unique_data: &'a [u8], diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index ccef621f05..27c8a87b8b 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -122,18 +122,23 @@ pub const MYCOIN: &str = "MYCOIN"; /// Ticker of MYCOIN1 dockerized blockchain. pub const MYCOIN1: &str = "MYCOIN1"; -pub const ERC20_TOKEN_BYTES: &str = "6080604052600860ff16600a0a633b9aca000260005534801561002157600080fd5b50600054600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610c69806100776000396000f3006080604052600436106100a4576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100a9578063095ea7b31461013957806318160ddd1461019e57806323b872dd146101c9578063313ce5671461024e5780635a3b7e421461027f57806370a082311461030f57806395d89b4114610366578063a9059cbb146103f6578063dd62ed3e1461045b575b600080fd5b3480156100b557600080fd5b506100be6104d2565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100fe5780820151818401526020810190506100e3565b50505050905090810190601f16801561012b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014557600080fd5b50610184600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061050b565b604051808215151515815260200191505060405180910390f35b3480156101aa57600080fd5b506101b36106bb565b6040518082815260200191505060405180910390f35b3480156101d557600080fd5b50610234600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506106c1565b604051808215151515815260200191505060405180910390f35b34801561025a57600080fd5b506102636109a1565b604051808260ff1660ff16815260200191505060405180910390f35b34801561028b57600080fd5b506102946109a6565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102d45780820151818401526020810190506102b9565b50505050905090810190601f1680156103015780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561031b57600080fd5b50610350600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109df565b6040518082815260200191505060405180910390f35b34801561037257600080fd5b5061037b6109f7565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103bb5780820151818401526020810190506103a0565b50505050905090810190601f1680156103e85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561040257600080fd5b50610441600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a30565b604051808215151515815260200191505060405180910390f35b34801561046757600080fd5b506104bc600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610be1565b6040518082815260200191505060405180910390f35b6040805190810160405280600881526020017f515243205445535400000000000000000000000000000000000000000000000081525081565b60008260008173ffffffffffffffffffffffffffffffffffffffff161415151561053457600080fd5b60008314806105bf57506000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054145b15156105ca57600080fd5b82600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925856040518082815260200191505060405180910390a3600191505092915050565b60005481565b60008360008173ffffffffffffffffffffffffffffffffffffffff16141515156106ea57600080fd5b8360008173ffffffffffffffffffffffffffffffffffffffff161415151561071157600080fd5b610797600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485610c06565b600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610860600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485610c06565b600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506108ec600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485610c1f565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef866040518082815260200191505060405180910390a36001925050509392505050565b600881565b6040805190810160405280600981526020017f546f6b656e20302e31000000000000000000000000000000000000000000000081525081565b60016020528060005260406000206000915090505481565b6040805190810160405280600381526020017f515443000000000000000000000000000000000000000000000000000000000081525081565b60008260008173ffffffffffffffffffffffffffffffffffffffff1614151515610a5957600080fd5b610aa2600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205484610c06565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610b2e600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205484610c1f565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191505092915050565b6002602052816000526040600020602052806000526040600020600091509150505481565b6000818310151515610c1457fe5b818303905092915050565b6000808284019050838110151515610c3357fe5b80915050929150505600a165627a7a723058207f2e5248b61b80365ea08a0f6d11ac0b47374c4dfd538de76bc2f19591bbbba40029"; -pub const SWAP_CONTRACT_BYTES: &str = "608060405234801561001057600080fd5b50611437806100206000396000f3fe60806040526004361061004a5760003560e01c806302ed292b1461004f5780630716326d146100de578063152cf3af1461017b57806346fc0294146101f65780639b415b2a14610294575b600080fd5b34801561005b57600080fd5b506100dc600480360360a081101561007257600080fd5b81019080803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610339565b005b3480156100ea57600080fd5b506101176004803603602081101561010157600080fd5b8101908080359060200190929190505050610867565b60405180846bffffffffffffffffffffffff19166bffffffffffffffffffffffff191681526020018367ffffffffffffffff1667ffffffffffffffff16815260200182600381111561016557fe5b60ff168152602001935050505060405180910390f35b6101f46004803603608081101561019157600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080356bffffffffffffffffffffffff19169060200190929190803567ffffffffffffffff1690602001909291905050506108bf565b005b34801561020257600080fd5b50610292600480360360a081101561021957600080fd5b81019080803590602001909291908035906020019092919080356bffffffffffffffffffffffff19169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bd9565b005b610337600480360360c08110156102aa57600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080356bffffffffffffffffffffffff19169060200190929190803567ffffffffffffffff169060200190929190505050610fe2565b005b6001600381111561034657fe5b600080878152602001908152602001600020600001601c9054906101000a900460ff16600381111561037457fe5b1461037e57600080fd5b6000600333836003600288604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b602083106103db57805182526020820191506020810190506020830392506103b8565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa15801561041d573d6000803e3d6000fd5b5050506040513d602081101561043257600080fd5b8101908080519060200190929190505050604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b602083106104955780518252602082019150602081019050602083039250610472565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa1580156104d7573d6000803e3d6000fd5b5050506040515160601b8689604051602001808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401846bffffffffffffffffffffffff19166bffffffffffffffffffffffff191681526014018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401828152602001955050505050506040516020818303038152906040526040518082805190602001908083835b602083106105fc57805182526020820191506020810190506020830392506105d9565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa15801561063e573d6000803e3d6000fd5b5050506040515160601b905060008087815260200190815260200160002060000160009054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461069657600080fd5b6002600080888152602001908152602001600020600001601c6101000a81548160ff021916908360038111156106c857fe5b0217905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561074e573373ffffffffffffffffffffffffffffffffffffffff166108fc869081150290604051600060405180830381858888f19350505050158015610748573d6000803e3d6000fd5b50610820565b60008390508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33886040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156107da57600080fd5b505af11580156107ee573d6000803e3d6000fd5b505050506040513d602081101561080457600080fd5b810190808051906020019092919050505061081e57600080fd5b505b7f36c177bcb01c6d568244f05261e2946c8c977fa50822f3fa098c470770ee1f3e8685604051808381526020018281526020019250505060405180910390a1505050505050565b60006020528060005260406000206000915090508060000160009054906101000a900460601b908060000160149054906101000a900467ffffffffffffffff169080600001601c9054906101000a900460ff16905083565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156108fc5750600034115b801561094057506000600381111561091057fe5b600080868152602001908152602001600020600001601c9054906101000a900460ff16600381111561093e57fe5b145b61094957600080fd5b60006003843385600034604051602001808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401846bffffffffffffffffffffffff19166bffffffffffffffffffffffff191681526014018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401828152602001955050505050506040516020818303038152906040526040518082805190602001908083835b60208310610a6c5780518252602082019150602081019050602083039250610a49565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610aae573d6000803e3d6000fd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018367ffffffffffffffff16815260200160016003811115610af757fe5b81525060008087815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c021790555060208201518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550604082015181600001601c6101000a81548160ff02191690836003811115610b9357fe5b02179055509050507fccc9c05183599bd3135da606eaaf535daffe256e9de33c048014cffcccd4ad57856040518082815260200191505060405180910390a15050505050565b60016003811115610be657fe5b600080878152602001908152602001600020600001601c9054906101000a900460ff166003811115610c1457fe5b14610c1e57600080fd5b600060038233868689604051602001808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401846bffffffffffffffffffffffff19166bffffffffffffffffffffffff191681526014018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401828152602001955050505050506040516020818303038152906040526040518082805190602001908083835b60208310610d405780518252602082019150602081019050602083039250610d1d565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610d82573d6000803e3d6000fd5b5050506040515160601b905060008087815260200190815260200160002060000160009054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916148015610e10575060008087815260200190815260200160002060000160149054906101000a900467ffffffffffffffff1667ffffffffffffffff164210155b610e1957600080fd5b6003600080888152602001908152602001600020600001601c6101000a81548160ff02191690836003811115610e4b57fe5b0217905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610ed1573373ffffffffffffffffffffffffffffffffffffffff166108fc869081150290604051600060405180830381858888f19350505050158015610ecb573d6000803e3d6000fd5b50610fa3565b60008390508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33886040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610f5d57600080fd5b505af1158015610f71573d6000803e3d6000fd5b505050506040513d6020811015610f8757600080fd5b8101908080519060200190929190505050610fa157600080fd5b505b7f1797d500133f8e427eb9da9523aa4a25cb40f50ebc7dbda3c7c81778973f35ba866040518082815260200191505060405180910390a1505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561101f5750600085115b801561106357506000600381111561103357fe5b600080888152602001908152602001600020600001601c9054906101000a900460ff16600381111561106157fe5b145b61106c57600080fd5b60006003843385888a604051602001808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401846bffffffffffffffffffffffff19166bffffffffffffffffffffffff191681526014018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401828152602001955050505050506040516020818303038152906040526040518082805190602001908083835b6020831061118e578051825260208201915060208101905060208303925061116b565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa1580156111d0573d6000803e3d6000fd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018367ffffffffffffffff1681526020016001600381111561121957fe5b81525060008089815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c021790555060208201518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550604082015181600001601c6101000a81548160ff021916908360038111156112b557fe5b021790555090505060008590508073ffffffffffffffffffffffffffffffffffffffff166323b872dd33308a6040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561137d57600080fd5b505af1158015611391573d6000803e3d6000fd5b505050506040513d60208110156113a757600080fd5b81019080805190602001909291905050506113c157600080fd5b7fccc9c05183599bd3135da606eaaf535daffe256e9de33c048014cffcccd4ad57886040518082815260200191505060405180910390a1505050505050505056fea265627a7a723158208c83db436905afce0b7be1012be64818c49323c12d451fe2ab6bce76ff6421c964736f6c63430005110032"; -pub const WATCHERS_SWAP_CONTRACT_BYTES: &str = "608060405234801561000f575f80fd5b50612aa48061001d5f395ff3fe608060405260043610610085575f3560e01c806346fc02941161005857806346fc0294146101275780636a3227861461014f5780639b415b2a1461016b578063b5985c4d14610193578063cd1dde34146101bb57610085565b806302ed292b146100895780630716326d146100b15780630971fd54146100ef578063152cf3af1461010b575b5f80fd5b348015610094575f80fd5b506100af60048036038101906100aa9190611e1d565b6101e3565b005b3480156100bc575f80fd5b506100d760048036038101906100d29190611e94565b610518565b6040516100e693929190611f8e565b60405180910390f35b6101096004803603810190610104919061206f565b610568565b005b6101256004803603810190610120919061210c565b610787565b005b348015610132575f80fd5b5061014d60048036038101906101489190612170565b61099d565b005b610169600480360381019061016491906121e7565b610c4d565b005b348015610176575f80fd5b50610191600480360381019061018c91906122ab565b610f61565b005b34801561019e575f80fd5b506101b960048036038101906101b49190612334565b611203565b005b3480156101c6575f80fd5b506101e160048036038101906101dc91906123f8565b611887565b005b600160038111156101f7576101f6611f1b565b5b5f808781526020019081526020015f205f01601c9054906101000a900460ff16600381111561022957610228611f1b565b5b14610232575f80fd5b5f60033383600360028860405160200161024c91906124dc565b6040516020818303038152906040526040516102689190612562565b602060405180830381855afa158015610283573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906102a6919061258c565b6040516020016102b691906124dc565b6040516020818303038152906040526040516102d29190612562565b602060405180830381855afa1580156102ed573d5f803e3d5ffd5b5050506040515160601b868960405160200161030d95949392919061263c565b6040516020818303038152906040526040516103299190612562565b602060405180830381855afa158015610344573d5f803e3d5ffd5b5050506040515160601b90505f808781526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610397575f80fd5b60025f808881526020019081526020015f205f01601c6101000a81548160ff021916908360038111156103cd576103cc611f1b565b5b02179055505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361044e573373ffffffffffffffffffffffffffffffffffffffff166108fc8690811502906040515f60405180830381858888f19350505050158015610448573d5f803e3d5ffd5b506104d7565b5f8390508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33886040518363ffffffff1660e01b815260040161048d9291906126b8565b6020604051808303815f875af11580156104a9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104cd91906126f3565b6104d5575f80fd5b505b7f36c177bcb01c6d568244f05261e2946c8c977fa50822f3fa098c470770ee1f3e868560405161050892919061272d565b60405180910390a1505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900467ffffffffffffffff1690805f01601c9054906101000a900460ff16905083565b5f73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16141580156105a357505f34115b80156105f157505f60038111156105bd576105bc611f1b565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660038111156105ef576105ee611f1b565b5b145b6105f9575f80fd5b5f60038733885f3489898960405160200161061b9897969594939291906127e7565b6040516020818303038152906040526040516106379190612562565b602060405180830381855afa158015610652573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018667ffffffffffffffff168152602001600160038111156106a2576106a1611f1b565b5b8152505f808a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040820151815f01601c6101000a81548160ff0219169083600381111561073e5761073d611f1b565b5b02179055509050507fccc9c05183599bd3135da606eaaf535daffe256e9de33c048014cffcccd4ad57886040516107759190612878565b60405180910390a15050505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156107c257505f34115b801561081057505f60038111156107dc576107db611f1b565b5b5f808681526020019081526020015f205f01601c9054906101000a900460ff16600381111561080e5761080d611f1b565b5b145b610818575f80fd5b5f60038433855f3460405160200161083495949392919061263c565b6040516020818303038152906040526040516108509190612562565b602060405180830381855afa15801561086b573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018367ffffffffffffffff168152602001600160038111156108bb576108ba611f1b565b5b8152505f808781526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040820151815f01601c6101000a81548160ff0219169083600381111561095757610956611f1b565b5b02179055509050507fccc9c05183599bd3135da606eaaf535daffe256e9de33c048014cffcccd4ad578560405161098e9190612878565b60405180910390a15050505050565b600160038111156109b1576109b0611f1b565b5b5f808781526020019081526020015f205f01601c9054906101000a900460ff1660038111156109e3576109e2611f1b565b5b146109ec575f80fd5b5f60038233868689604051602001610a0895949392919061263c565b604051602081830303815290604052604051610a249190612562565b602060405180830381855afa158015610a3f573d5f803e3d5ffd5b5050506040515160601b90505f808781526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916148015610ac657505f808781526020019081526020015f205f0160149054906101000a900467ffffffffffffffff1667ffffffffffffffff164210155b610ace575f80fd5b60035f808881526020019081526020015f205f01601c6101000a81548160ff02191690836003811115610b0457610b03611f1b565b5b02179055505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b85573373ffffffffffffffffffffffffffffffffffffffff166108fc8690811502906040515f60405180830381858888f19350505050158015610b7f573d5f803e3d5ffd5b50610c0e565b5f8390508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33886040518363ffffffff1660e01b8152600401610bc49291906126b8565b6020604051808303815f875af1158015610be0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c0491906126f3565b610c0c575f80fd5b505b7f1797d500133f8e427eb9da9523aa4a25cb40f50ebc7dbda3c7c81778973f35ba86604051610c3d9190612878565b60405180910390a1505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614158015610c8857505f88115b8015610cd657505f6003811115610ca257610ca1611f1b565b5b5f808b81526020019081526020015f205f01601c9054906101000a900460ff166003811115610cd457610cd3611f1b565b5b145b610cde575f80fd5b5f6003811115610cf157610cf0611f1b565b5b836003811115610d0457610d03611f1b565b5b14158015610d365750600380811115610d2057610d1f611f1b565b5b836003811115610d3357610d32611f1b565b5b14155b15610d4757803414610d46575f80fd5b5b5f60038733888b8d898989604051602001610d699897969594939291906127e7565b604051602081830303815290604052604051610d859190612562565b602060405180830381855afa158015610da0573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018667ffffffffffffffff16815260200160016003811115610df057610def611f1b565b5b8152505f808c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040820151815f01601c6101000a81548160ff02191690836003811115610e8c57610e8b611f1b565b5b02179055509050505f8890508073ffffffffffffffffffffffffffffffffffffffff166323b872dd33308d6040518463ffffffff1660e01b8152600401610ed593929190612891565b6020604051808303815f875af1158015610ef1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f1591906126f3565b610f1d575f80fd5b7fccc9c05183599bd3135da606eaaf535daffe256e9de33c048014cffcccd4ad578b604051610f4c9190612878565b60405180910390a15050505050505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015610f9c57505f85115b8015610fea57505f6003811115610fb657610fb5611f1b565b5b5f808881526020019081526020015f205f01601c9054906101000a900460ff166003811115610fe857610fe7611f1b565b5b145b610ff2575f80fd5b5f6003843385888a60405160200161100e95949392919061263c565b60405160208183030381529060405260405161102a9190612562565b602060405180830381855afa158015611045573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018367ffffffffffffffff1681526020016001600381111561109557611094611f1b565b5b8152505f808981526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040820151815f01601c6101000a81548160ff0219169083600381111561113157611130611f1b565b5b02179055509050505f8590508073ffffffffffffffffffffffffffffffffffffffff166323b872dd33308a6040518463ffffffff1660e01b815260040161117a93929190612891565b6020604051808303815f875af1158015611196573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ba91906126f3565b6111c2575f80fd5b7fccc9c05183599bd3135da606eaaf535daffe256e9de33c048014cffcccd4ad57886040516111f19190612878565b60405180910390a15050505050505050565b6001600381111561121757611216611f1b565b5b5f808b81526020019081526020015f205f01601c9054906101000a900460ff16600381111561124957611248611f1b565b5b14611289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128090612920565b60405180910390fd5b5f60038587600360028c6040516020016112a391906124dc565b6040516020818303038152906040526040516112bf9190612562565b602060405180830381855afa1580156112da573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906112fd919061258c565b60405160200161130d91906124dc565b6040516020818303038152906040526040516113299190612562565b602060405180830381855afa158015611344573d5f803e3d5ffd5b5050506040515160601b8a8d89898960405160200161136a9897969594939291906127e7565b6040516020818303038152906040526040516113869190612562565b602060405180830381855afa1580156113a1573d5f803e3d5ffd5b5050506040515160601b90505f808b81526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461142b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142290612988565b60405180910390fd5b60025f808c81526020019081526020015f205f01601c6101000a81548160ff0219169083600381111561146157611460611f1b565b5b02179055505f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff160361159e575f8060038111156114ad576114ac611f1b565b5b8560038111156114c0576114bf611f1b565b5b1480156114cb575083155b6114e057828a6114db91906129d3565b6114e2565b895b90508573ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015611527573d5f803e3d5ffd5b5060038081111561153b5761153a611f1b565b5b85600381111561154e5761154d611f1b565b5b03611598573373ffffffffffffffffffffffffffffffffffffffff166108fc8490811502906040515f60405180830381858888f19350505050158015611596573d5f803e3d5ffd5b505b50611786565b5f6003808111156115b2576115b1611f1b565b5b8560038111156115c5576115c4611f1b565b5b146115d057896115dd565b828a6115dc91906129d3565b5b90505f8890508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb88846040518363ffffffff1660e01b815260040161161e9291906126b8565b6020604051808303815f875af115801561163a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061165e91906126f3565b61169d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169490612a50565b60405180910390fd5b6003808111156116b0576116af611f1b565b5b8660038111156116c3576116c2611f1b565b5b03611783578073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33866040518363ffffffff1660e01b81526004016117039291906126b8565b6020604051808303815f875af115801561171f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061174391906126f3565b611782576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177990612a50565b60405180910390fd5b5b50505b6002600381111561179a57611799611f1b565b5b8460038111156117ad576117ac611f1b565b5b036117f7578573ffffffffffffffffffffffffffffffffffffffff166108fc8390811502906040515f60405180830381858888f193505050501580156117f5573d5f803e3d5ffd5b505b8215611842573373ffffffffffffffffffffffffffffffffffffffff166108fc8390811502906040515f60405180830381858888f19350505050158015611840573d5f803e3d5ffd5b505b7f36c177bcb01c6d568244f05261e2946c8c977fa50822f3fa098c470770ee1f3e8a8960405161187392919061272d565b60405180910390a150505050505050505050565b6001600381111561189b5761189a611f1b565b5b5f808b81526020019081526020015f205f01601c9054906101000a900460ff1660038111156118cd576118cc611f1b565b5b146118d6575f80fd5b5f600385878a8a8d8989896040516020016118f89897969594939291906127e7565b6040516020818303038152906040526040516119149190612562565b602060405180830381855afa15801561192f573d5f803e3d5ffd5b5050506040515160601b90505f808b81526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161480156119b657505f808b81526020019081526020015f205f0160149054906101000a900467ffffffffffffffff1667ffffffffffffffff164210155b6119be575f80fd5b60035f808c81526020019081526020015f205f01601c6101000a81548160ff021916908360038111156119f4576119f3611f1b565b5b02179055505f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1603611b27575f806003811115611a4057611a3f611f1b565b5b856003811115611a5357611a52611f1b565b5b14611a6957828a611a6491906129d3565b611a6b565b895b90508673ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015611ab0573d5f803e3d5ffd5b505f6003811115611ac457611ac3611f1b565b5b856003811115611ad757611ad6611f1b565b5b14611b21573373ffffffffffffffffffffffffffffffffffffffff166108fc8490811502906040515f60405180830381858888f19350505050158015611b1f573d5f803e3d5ffd5b505b50611d16565b5f600380811115611b3b57611b3a611f1b565b5b856003811115611b4e57611b4d611f1b565b5b14611b595789611b66565b828a611b6591906129d3565b5b90505f8890508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb89846040518363ffffffff1660e01b8152600401611ba79291906126b8565b6020604051808303815f875af1158015611bc3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611be791906126f3565b611bef575f80fd5b600380811115611c0257611c01611f1b565b5b866003811115611c1557611c14611f1b565b5b03611ca2578073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33866040518363ffffffff1660e01b8152600401611c559291906126b8565b6020604051808303815f875af1158015611c71573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c9591906126f3565b611c9d575f80fd5b611d13565b5f6003811115611cb557611cb4611f1b565b5b866003811115611cc857611cc7611f1b565b5b14611d12573373ffffffffffffffffffffffffffffffffffffffff166108fc8590811502906040515f60405180830381858888f19350505050158015611d10573d5f803e3d5ffd5b505b5b50505b7f1797d500133f8e427eb9da9523aa4a25cb40f50ebc7dbda3c7c81778973f35ba8a604051611d459190612878565b60405180910390a150505050505050505050565b5f80fd5b5f819050919050565b611d6f81611d5d565b8114611d79575f80fd5b50565b5f81359050611d8a81611d66565b92915050565b5f819050919050565b611da281611d90565b8114611dac575f80fd5b50565b5f81359050611dbd81611d99565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611dec82611dc3565b9050919050565b611dfc81611de2565b8114611e06575f80fd5b50565b5f81359050611e1781611df3565b92915050565b5f805f805f60a08688031215611e3657611e35611d59565b5b5f611e4388828901611d7c565b9550506020611e5488828901611daf565b9450506040611e6588828901611d7c565b9350506060611e7688828901611e09565b9250506080611e8788828901611e09565b9150509295509295909350565b5f60208284031215611ea957611ea8611d59565b5b5f611eb684828501611d7c565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b611ef381611ebf565b82525050565b5f67ffffffffffffffff82169050919050565b611f1581611ef9565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60048110611f5957611f58611f1b565b5b50565b5f819050611f6982611f48565b919050565b5f611f7882611f5c565b9050919050565b611f8881611f6e565b82525050565b5f606082019050611fa15f830186611eea565b611fae6020830185611f0c565b611fbb6040830184611f7f565b949350505050565b611fcc81611ebf565b8114611fd6575f80fd5b50565b5f81359050611fe781611fc3565b92915050565b611ff681611ef9565b8114612000575f80fd5b50565b5f8135905061201181611fed565b92915050565b60048110612023575f80fd5b50565b5f8135905061203481612017565b92915050565b5f8115159050919050565b61204e8161203a565b8114612058575f80fd5b50565b5f8135905061206981612045565b92915050565b5f805f805f805f60e0888a03121561208a57612089611d59565b5b5f6120978a828b01611d7c565b97505060206120a88a828b01611e09565b96505060406120b98a828b01611fd9565b95505060606120ca8a828b01612003565b94505060806120db8a828b01612026565b93505060a06120ec8a828b0161205b565b92505060c06120fd8a828b01611daf565b91505092959891949750929550565b5f805f806080858703121561212457612123611d59565b5b5f61213187828801611d7c565b945050602061214287828801611e09565b935050604061215387828801611fd9565b925050606061216487828801612003565b91505092959194509250565b5f805f805f60a0868803121561218957612188611d59565b5b5f61219688828901611d7c565b95505060206121a788828901611daf565b94505060406121b888828901611fd9565b93505060606121c988828901611e09565b92505060806121da88828901611e09565b9150509295509295909350565b5f805f805f805f805f6101208a8c03121561220557612204611d59565b5b5f6122128c828d01611d7c565b99505060206122238c828d01611daf565b98505060406122348c828d01611e09565b97505060606122458c828d01611e09565b96505060806122568c828d01611fd9565b95505060a06122678c828d01612003565b94505060c06122788c828d01612026565b93505060e06122898c828d0161205b565b92505061010061229b8c828d01611daf565b9150509295985092959850929598565b5f805f805f8060c087890312156122c5576122c4611d59565b5b5f6122d289828a01611d7c565b96505060206122e389828a01611daf565b95505060406122f489828a01611e09565b945050606061230589828a01611e09565b935050608061231689828a01611fd9565b92505060a061232789828a01612003565b9150509295509295509295565b5f805f805f805f805f6101208a8c03121561235257612351611d59565b5b5f61235f8c828d01611d7c565b99505060206123708c828d01611daf565b98505060406123818c828d01611d7c565b97505060606123928c828d01611e09565b96505060806123a38c828d01611e09565b95505060a06123b48c828d01611e09565b94505060c06123c58c828d01612026565b93505060e06123d68c828d0161205b565b9250506101006123e88c828d01611daf565b9150509295985092959850929598565b5f805f805f805f805f6101208a8c03121561241657612415611d59565b5b5f6124238c828d01611d7c565b99505060206124348c828d01611daf565b98505060406124458c828d01611fd9565b97505060606124568c828d01611e09565b96505060806124678c828d01611e09565b95505060a06124788c828d01611e09565b94505060c06124898c828d01612026565b93505060e061249a8c828d0161205b565b9250506101006124ac8c828d01611daf565b9150509295985092959850929598565b5f819050919050565b6124d66124d182611d5d565b6124bc565b82525050565b5f6124e782846124c5565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b5f5b8381101561252757808201518184015260208101905061250c565b5f8484015250505050565b5f61253c826124f6565b6125468185612500565b935061255681856020860161250a565b80840191505092915050565b5f61256d8284612532565b915081905092915050565b5f8151905061258681611d66565b92915050565b5f602082840312156125a1576125a0611d59565b5b5f6125ae84828501612578565b91505092915050565b5f8160601b9050919050565b5f6125cd826125b7565b9050919050565b5f6125de826125c3565b9050919050565b6125f66125f182611de2565b6125d4565b82525050565b5f819050919050565b61261661261182611ebf565b6125fc565b82525050565b5f819050919050565b61263661263182611d90565b61261c565b82525050565b5f61264782886125e5565b60148201915061265782876125e5565b6014820191506126678286612605565b60148201915061267782856125e5565b6014820191506126878284612625565b6020820191508190509695505050505050565b6126a381611de2565b82525050565b6126b281611d90565b82525050565b5f6040820190506126cb5f83018561269a565b6126d860208301846126a9565b9392505050565b5f815190506126ed81612045565b92915050565b5f6020828403121561270857612707611d59565b5b5f612715848285016126df565b91505092915050565b61272781611d5d565b82525050565b5f6040820190506127405f83018561271e565b61274d602083018461271e565b9392505050565b6004811061276557612764611f1b565b5b50565b5f81905061277582612754565b919050565b5f61278482612768565b9050919050565b5f8160f81b9050919050565b5f6127a18261278b565b9050919050565b6127b96127b48261277a565b612797565b82525050565b5f6127c982612797565b9050919050565b6127e16127dc8261203a565b6127bf565b82525050565b5f6127f2828b6125e5565b601482019150612802828a6125e5565b6014820191506128128289612605565b60148201915061282282886125e5565b6014820191506128328287612625565b60208201915061284282866127a8565b60018201915061285282856127d0565b6001820191506128628284612625565b6020820191508190509998505050505050505050565b5f60208201905061288b5f83018461271e565b92915050565b5f6060820190506128a45f83018661269a565b6128b1602083018561269a565b6128be60408301846126a9565b949350505050565b5f82825260208201905092915050565b7f5061796d656e7420776173206e6f742073656e740000000000000000000000005f82015250565b5f61290a6014836128c6565b9150612915826128d6565b602082019050919050565b5f6020820190508181035f830152612937816128fe565b9050919050565b7f496e76616c6964207061796d656e7420686173680000000000000000000000005f82015250565b5f6129726014836128c6565b915061297d8261293e565b602082019050919050565b5f6020820190508181035f83015261299f81612966565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6129dd82611d90565b91506129e883611d90565b9250828203905081811115612a00576129ff6129a6565b5b92915050565b7f546f6b656e207472616e73666572206661696c656400000000000000000000005f82015250565b5f612a3a6015836128c6565b9150612a4582612a06565b602082019050919050565b5f6020820190508181035f830152612a6781612a2e565b905091905056fea26469706673582212203106867e1b147b377237cde0aba42d82faf0282b83d7b6d62cca039d0b7f840564736f6c63430008160033"; -pub const ERC721_TEST_TOKEN_BYTES: &str = "608060405234801562000010575f80fd5b50604051620022ac380380620022ac8339818101604052810190620000369190620001ea565b8181815f9081620000489190620004a4565b5080600190816200005a9190620004a4565b505050505062000588565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c6826200007e565b810181811067ffffffffffffffff82111715620000e857620000e76200008e565b5b80604052505050565b5f620000fc62000065565b90506200010a8282620000bb565b919050565b5f67ffffffffffffffff8211156200012c576200012b6200008e565b5b62000137826200007e565b9050602081019050919050565b5f5b838110156200016357808201518184015260208101905062000146565b5f8484015250505050565b5f620001846200017e846200010f565b620000f1565b905082815260208101848484011115620001a357620001a26200007a565b5b620001b084828562000144565b509392505050565b5f82601f830112620001cf57620001ce62000076565b5b8151620001e18482602086016200016e565b91505092915050565b5f80604083850312156200020357620002026200006e565b5b5f83015167ffffffffffffffff81111562000223576200022262000072565b5b6200023185828601620001b8565b925050602083015167ffffffffffffffff81111562000255576200025462000072565b5b6200026385828601620001b8565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620002bc57607f821691505b602082108103620002d257620002d162000277565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002f9565b620003428683620002f9565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200038c6200038662000380846200035a565b62000363565b6200035a565b9050919050565b5f819050919050565b620003a7836200036c565b620003bf620003b68262000393565b84845462000305565b825550505050565b5f90565b620003d5620003c7565b620003e28184846200039c565b505050565b5b818110156200040957620003fd5f82620003cb565b600181019050620003e8565b5050565b601f82111562000458576200042281620002d8565b6200042d84620002ea565b810160208510156200043d578190505b620004556200044c85620002ea565b830182620003e7565b50505b505050565b5f82821c905092915050565b5f6200047a5f19846008026200045d565b1980831691505092915050565b5f62000494838362000469565b9150826002028217905092915050565b620004af826200026d565b67ffffffffffffffff811115620004cb57620004ca6200008e565b5b620004d78254620002a4565b620004e48282856200040d565b5f60209050601f8311600181146200051a575f841562000505578287015190505b62000511858262000487565b86555062000580565b601f1984166200052a86620002d8565b5f5b8281101562000553578489015182556001820191506020850194506020810190506200052c565b868310156200057357848901516200056f601f89168262000469565b8355505b6001600288020188555050505b505050505050565b611d1680620005965f395ff3fe608060405234801561000f575f80fd5b50600436106100e8575f3560e01c80636352211e1161008a578063a22cb46511610064578063a22cb46514610258578063b88d4fde14610274578063c87b56dd14610290578063e985e9c5146102c0576100e8565b80636352211e146101da57806370a082311461020a57806395d89b411461023a576100e8565b8063095ea7b3116100c6578063095ea7b31461016a57806323b872dd1461018657806340c10f19146101a257806342842e0e146101be576100e8565b806301ffc9a7146100ec57806306fdde031461011c578063081812fc1461013a575b5f80fd5b610106600480360381019061010191906115a7565b6102f0565b60405161011391906115ec565b60405180910390f35b6101246103d1565b604051610131919061168f565b60405180910390f35b610154600480360381019061014f91906116e2565b610460565b604051610161919061174c565b60405180910390f35b610184600480360381019061017f919061178f565b61047b565b005b6101a0600480360381019061019b91906117cd565b610491565b005b6101bc60048036038101906101b7919061178f565b610590565b005b6101d860048036038101906101d391906117cd565b61059e565b005b6101f460048036038101906101ef91906116e2565b6105bd565b604051610201919061174c565b60405180910390f35b610224600480360381019061021f919061181d565b6105ce565b6040516102319190611857565b60405180910390f35b610242610684565b60405161024f919061168f565b60405180910390f35b610272600480360381019061026d919061189a565b610714565b005b61028e60048036038101906102899190611a04565b61072a565b005b6102aa60048036038101906102a591906116e2565b610747565b6040516102b7919061168f565b60405180910390f35b6102da60048036038101906102d59190611a84565b6107ad565b6040516102e791906115ec565b60405180910390f35b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103ba57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103ca57506103c98261083b565b5b9050919050565b60605f80546103df90611aef565b80601f016020809104026020016040519081016040528092919081815260200182805461040b90611aef565b80156104565780601f1061042d57610100808354040283529160200191610456565b820191905f5260205f20905b81548152906001019060200180831161043957829003601f168201915b5050505050905090565b5f61046a826108a4565b506104748261092a565b9050919050565b61048d8282610488610963565b61096a565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610501575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016104f8919061174c565b60405180910390fd5b5f610514838361050f610963565b61097c565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461058a578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161058193929190611b1f565b60405180910390fd5b50505050565b61059a8282610b87565b5050565b6105b883838360405180602001604052805f81525061072a565b505050565b5f6105c7826108a4565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361063f575f6040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401610636919061174c565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b60606001805461069390611aef565b80601f01602080910402602001604051908101604052809291908181526020018280546106bf90611aef565b801561070a5780601f106106e15761010080835404028352916020019161070a565b820191905f5260205f20905b8154815290600101906020018083116106ed57829003601f168201915b5050505050905090565b61072661071f610963565b8383610c7a565b5050565b610735848484610491565b61074184848484610de3565b50505050565b6060610752826108a4565b505f61075c610f95565b90505f81511161077a5760405180602001604052805f8152506107a5565b8061078484610fab565b604051602001610795929190611b8e565b6040516020818303038152906040525b915050919050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f806108af83611075565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361092157826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016109189190611857565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b61097783838360016110ae565b505050565b5f8061098784611075565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146109c8576109c781848661126d565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a5357610a075f855f806110ae565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610ad257600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610bf7575f6040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610bee919061174c565b60405180910390fd5b5f610c0383835f61097c565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c75575f6040517f73c6ac6e000000000000000000000000000000000000000000000000000000008152600401610c6c919061174c565b60405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610cea57816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401610ce1919061174c565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610dd691906115ec565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b1115610f8f578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02610e26610963565b8685856040518563ffffffff1660e01b8152600401610e489493929190611c03565b6020604051808303815f875af1925050508015610e8357506040513d601f19601f82011682018060405250810190610e809190611c61565b60015b610f04573d805f8114610eb1576040519150601f19603f3d011682016040523d82523d5f602084013e610eb6565b606091505b505f815103610efc57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610ef3919061174c565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614610f8d57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610f84919061174c565b60405180910390fd5b505b50505050565b606060405180602001604052805f815250905090565b60605f6001610fb984611330565b0190505f8167ffffffffffffffff811115610fd757610fd66118e0565b5b6040519080825280601f01601f1916602001820160405280156110095781602001600182028036833780820191505090505b5090505f82602001820190505b60011561106a578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161105f5761105e611c8c565b5b0494505f8503611016575b819350505050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b80806110e657505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611218575f6110f5846108a4565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561115f57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611172575061117081846107ad565b155b156111b457826040517fa9fbf51f0000000000000000000000000000000000000000000000000000000081526004016111ab919061174c565b60405180910390fd5b811561121657838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b611278838383611481565b61132b575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036112ec57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016112e39190611857565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401611322929190611cb9565b60405180910390fd5b505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061138c577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161138257611381611c8c565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106113c9576d04ee2d6d415b85acef810000000083816113bf576113be611c8c565b5b0492506020810190505b662386f26fc1000083106113f857662386f26fc1000083816113ee576113ed611c8c565b5b0492506010810190505b6305f5e1008310611421576305f5e100838161141757611416611c8c565b5b0492506008810190505b612710831061144657612710838161143c5761143b611c8c565b5b0492506004810190505b60648310611469576064838161145f5761145e611c8c565b5b0492506002810190505b600a8310611478576001810190505b80915050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561153857508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806114f957506114f884846107ad565b5b8061153757508273ffffffffffffffffffffffffffffffffffffffff1661151f8361092a565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61158681611552565b8114611590575f80fd5b50565b5f813590506115a18161157d565b92915050565b5f602082840312156115bc576115bb61154a565b5b5f6115c984828501611593565b91505092915050565b5f8115159050919050565b6115e6816115d2565b82525050565b5f6020820190506115ff5f8301846115dd565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561163c578082015181840152602081019050611621565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61166182611605565b61166b818561160f565b935061167b81856020860161161f565b61168481611647565b840191505092915050565b5f6020820190508181035f8301526116a78184611657565b905092915050565b5f819050919050565b6116c1816116af565b81146116cb575f80fd5b50565b5f813590506116dc816116b8565b92915050565b5f602082840312156116f7576116f661154a565b5b5f611704848285016116ce565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6117368261170d565b9050919050565b6117468161172c565b82525050565b5f60208201905061175f5f83018461173d565b92915050565b61176e8161172c565b8114611778575f80fd5b50565b5f8135905061178981611765565b92915050565b5f80604083850312156117a5576117a461154a565b5b5f6117b28582860161177b565b92505060206117c3858286016116ce565b9150509250929050565b5f805f606084860312156117e4576117e361154a565b5b5f6117f18682870161177b565b93505060206118028682870161177b565b9250506040611813868287016116ce565b9150509250925092565b5f602082840312156118325761183161154a565b5b5f61183f8482850161177b565b91505092915050565b611851816116af565b82525050565b5f60208201905061186a5f830184611848565b92915050565b611879816115d2565b8114611883575f80fd5b50565b5f8135905061189481611870565b92915050565b5f80604083850312156118b0576118af61154a565b5b5f6118bd8582860161177b565b92505060206118ce85828601611886565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61191682611647565b810181811067ffffffffffffffff82111715611935576119346118e0565b5b80604052505050565b5f611947611541565b9050611953828261190d565b919050565b5f67ffffffffffffffff821115611972576119716118e0565b5b61197b82611647565b9050602081019050919050565b828183375f83830152505050565b5f6119a86119a384611958565b61193e565b9050828152602081018484840111156119c4576119c36118dc565b5b6119cf848285611988565b509392505050565b5f82601f8301126119eb576119ea6118d8565b5b81356119fb848260208601611996565b91505092915050565b5f805f8060808587031215611a1c57611a1b61154a565b5b5f611a298782880161177b565b9450506020611a3a8782880161177b565b9350506040611a4b878288016116ce565b925050606085013567ffffffffffffffff811115611a6c57611a6b61154e565b5b611a78878288016119d7565b91505092959194509250565b5f8060408385031215611a9a57611a9961154a565b5b5f611aa78582860161177b565b9250506020611ab88582860161177b565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611b0657607f821691505b602082108103611b1957611b18611ac2565b5b50919050565b5f606082019050611b325f83018661173d565b611b3f6020830185611848565b611b4c604083018461173d565b949350505050565b5f81905092915050565b5f611b6882611605565b611b728185611b54565b9350611b8281856020860161161f565b80840191505092915050565b5f611b998285611b5e565b9150611ba58284611b5e565b91508190509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f611bd582611bb1565b611bdf8185611bbb565b9350611bef81856020860161161f565b611bf881611647565b840191505092915050565b5f608082019050611c165f83018761173d565b611c23602083018661173d565b611c306040830185611848565b8181036060830152611c428184611bcb565b905095945050505050565b5f81519050611c5b8161157d565b92915050565b5f60208284031215611c7657611c7561154a565b5b5f611c8384828501611c4d565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f604082019050611ccc5f83018561173d565b611cd96020830184611848565b939250505056fea26469706673582212207439b47c2a9a1624955997732075917bbf1da26949d000c778f561eb5687576164736f6c63430008180033"; -pub const ERC1155_TEST_TOKEN_BYTES: &str = "608060405234801562000010575f80fd5b50604051620024eb380380620024eb8339818101604052810190620000369190620001ea565b8062000048816200005060201b60201c565b505062000554565b806002908162000061919062000470565b5050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c6826200007e565b810181811067ffffffffffffffff82111715620000e857620000e76200008e565b5b80604052505050565b5f620000fc62000065565b90506200010a8282620000bb565b919050565b5f67ffffffffffffffff8211156200012c576200012b6200008e565b5b62000137826200007e565b9050602081019050919050565b5f5b838110156200016357808201518184015260208101905062000146565b5f8484015250505050565b5f620001846200017e846200010f565b620000f1565b905082815260208101848484011115620001a357620001a26200007a565b5b620001b084828562000144565b509392505050565b5f82601f830112620001cf57620001ce62000076565b5b8151620001e18482602086016200016e565b91505092915050565b5f602082840312156200020257620002016200006e565b5b5f82015167ffffffffffffffff81111562000222576200022162000072565b5b6200023084828501620001b8565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200028857607f821691505b6020821081036200029e576200029d62000243565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002c5565b6200030e8683620002c5565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f62000358620003526200034c8462000326565b6200032f565b62000326565b9050919050565b5f819050919050565b620003738362000338565b6200038b62000382826200035f565b848454620002d1565b825550505050565b5f90565b620003a162000393565b620003ae81848462000368565b505050565b5b81811015620003d557620003c95f8262000397565b600181019050620003b4565b5050565b601f8211156200042457620003ee81620002a4565b620003f984620002b6565b8101602085101562000409578190505b620004216200041885620002b6565b830182620003b3565b50505b505050565b5f82821c905092915050565b5f620004465f198460080262000429565b1980831691505092915050565b5f62000460838362000435565b9150826002028217905092915050565b6200047b8262000239565b67ffffffffffffffff8111156200049757620004966200008e565b5b620004a3825462000270565b620004b0828285620003d9565b5f60209050601f831160018114620004e6575f8415620004d1578287015190505b620004dd858262000453565b8655506200054c565b601f198416620004f686620002a4565b5f5b828110156200051f57848901518255600182019150602085019450602081019050620004f8565b868310156200053f57848901516200053b601f89168262000435565b8355505b6001600288020188555050505b505050505050565b611f8980620005625f395ff3fe608060405234801561000f575f80fd5b5060043610610090575f3560e01c80634e1273f4116100645780634e1273f414610140578063731133e914610170578063a22cb4651461018c578063e985e9c5146101a8578063f242432a146101d857610090565b8062fdd58e1461009457806301ffc9a7146100c45780630e89341c146100f45780632eb2c2d614610124575b5f80fd5b6100ae60048036038101906100a991906113bd565b6101f4565b6040516100bb919061140a565b60405180910390f35b6100de60048036038101906100d99190611478565b610249565b6040516100eb91906114bd565b60405180910390f35b61010e600480360381019061010991906114d6565b61032a565b60405161011b919061158b565b60405180910390f35b61013e6004803603810190610139919061179b565b6103bc565b005b61015a60048036038101906101559190611926565b610463565b6040516101679190611a53565b60405180910390f35b61018a60048036038101906101859190611a73565b61056a565b005b6101a660048036038101906101a19190611b1d565b61057c565b005b6101c260048036038101906101bd9190611b5b565b610592565b6040516101cf91906114bd565b60405180910390f35b6101f260048036038101906101ed9190611b99565b610620565b005b5f805f8381526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f7fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061031357507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103235750610322826106c7565b5b9050919050565b60606002805461033990611c59565b80601f016020809104026020016040519081016040528092919081815260200182805461036590611c59565b80156103b05780601f10610387576101008083540402835291602001916103b0565b820191905f5260205f20905b81548152906001019060200180831161039357829003601f168201915b50505050509050919050565b5f6103c5610730565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561040a57506104088682610592565b155b1561044e5780866040517fe237d922000000000000000000000000000000000000000000000000000000008152600401610445929190611c98565b60405180910390fd5b61045b8686868686610737565b505050505050565b606081518351146104af57815183516040517f5b0599910000000000000000000000000000000000000000000000000000000081526004016104a6929190611cbf565b60405180910390fd5b5f835167ffffffffffffffff8111156104cb576104ca6115af565b5b6040519080825280602002602001820160405280156104f95781602001602082028036833780820191505090505b5090505f5b845181101561055f5761053561051d828761082b90919063ffffffff16565b610530838761083e90919063ffffffff16565b6101f4565b82828151811061054857610547611ce6565b5b6020026020010181815250508060010190506104fe565b508091505092915050565b61057684848484610851565b50505050565b61058e610587610730565b83836108e6565b5050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f610629610730565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561066e575061066c8682610592565b155b156106b25780866040517fe237d9220000000000000000000000000000000000000000000000000000000081526004016106a9929190611c98565b60405180910390fd5b6106bf8686868686610a4f565b505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036107a7575f6040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161079e9190611d13565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610817575f6040517f01a8351400000000000000000000000000000000000000000000000000000000815260040161080e9190611d13565b60405180910390fd5b6108248585858585610b55565b5050505050565b5f60208202602084010151905092915050565b5f60208202602084010151905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036108c1575f6040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016108b89190611d13565b60405180910390fd5b5f806108cd8585610c01565b915091506108de5f87848487610b55565b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610956575f6040517fced3e10000000000000000000000000000000000000000000000000000000000815260040161094d9190611d13565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610a4291906114bd565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610abf575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401610ab69190611d13565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610b2f575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401610b269190611d13565b60405180910390fd5b5f80610b3b8585610c01565b91509150610b4c8787848487610b55565b50505050505050565b610b6185858585610c31565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610bfa575f610b9d610730565b90506001845103610be9575f610bbc5f8661083e90919063ffffffff16565b90505f610bd25f8661083e90919063ffffffff16565b9050610be2838989858589610fc1565b5050610bf8565b610bf7818787878787611170565b5b505b5050505050565b60608060405191506001825283602083015260408201905060018152826020820152604081016040529250929050565b8051825114610c7b57815181516040517f5b059991000000000000000000000000000000000000000000000000000000008152600401610c72929190611cbf565b60405180910390fd5b5f610c84610730565b90505f5b8351811015610e80575f610ca5828661083e90919063ffffffff16565b90505f610cbb838661083e90919063ffffffff16565b90505f73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614610dde575f805f8481526020019081526020015f205f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015610d8a57888183856040517f03dee4c5000000000000000000000000000000000000000000000000000000008152600401610d819493929190611d2c565b60405180910390fd5b8181035f808581526020019081526020015f205f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610e7357805f808481526020019081526020015f205f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610e6b9190611d9c565b925050819055505b5050806001019050610c88565b506001835103610f3b575f610e9e5f8561083e90919063ffffffff16565b90505f610eb45f8561083e90919063ffffffff16565b90508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051610f2c929190611cbf565b60405180910390a45050610fba565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051610fb1929190611dcf565b60405180910390a45b5050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115611168578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b8152600401611021959493929190611e56565b6020604051808303815f875af192505050801561105c57506040513d601f19601f820116820180604052508101906110599190611ec2565b60015b6110dd573d805f811461108a576040519150601f19603f3d011682016040523d82523d5f602084013e61108f565b606091505b505f8151036110d557846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016110cc9190611d13565b60405180910390fd5b805181602001fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461116657846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161115d9190611d13565b60405180910390fd5b505b505050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115611317578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b81526004016111d0959493929190611eed565b6020604051808303815f875af192505050801561120b57506040513d601f19601f820116820180604052508101906112089190611ec2565b60015b61128c573d805f8114611239576040519150601f19603f3d011682016040523d82523d5f602084013e61123e565b606091505b505f81510361128457846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161127b9190611d13565b60405180910390fd5b805181602001fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461131557846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161130c9190611d13565b60405180910390fd5b505b505050505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61135982611330565b9050919050565b6113698161134f565b8114611373575f80fd5b50565b5f8135905061138481611360565b92915050565b5f819050919050565b61139c8161138a565b81146113a6575f80fd5b50565b5f813590506113b781611393565b92915050565b5f80604083850312156113d3576113d2611328565b5b5f6113e085828601611376565b92505060206113f1858286016113a9565b9150509250929050565b6114048161138a565b82525050565b5f60208201905061141d5f8301846113fb565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61145781611423565b8114611461575f80fd5b50565b5f813590506114728161144e565b92915050565b5f6020828403121561148d5761148c611328565b5b5f61149a84828501611464565b91505092915050565b5f8115159050919050565b6114b7816114a3565b82525050565b5f6020820190506114d05f8301846114ae565b92915050565b5f602082840312156114eb576114ea611328565b5b5f6114f8848285016113a9565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561153857808201518184015260208101905061151d565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61155d82611501565b611567818561150b565b935061157781856020860161151b565b61158081611543565b840191505092915050565b5f6020820190508181035f8301526115a38184611553565b905092915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6115e582611543565b810181811067ffffffffffffffff82111715611604576116036115af565b5b80604052505050565b5f61161661131f565b905061162282826115dc565b919050565b5f67ffffffffffffffff821115611641576116406115af565b5b602082029050602081019050919050565b5f80fd5b5f61166861166384611627565b61160d565b9050808382526020820190506020840283018581111561168b5761168a611652565b5b835b818110156116b457806116a088826113a9565b84526020840193505060208101905061168d565b5050509392505050565b5f82601f8301126116d2576116d16115ab565b5b81356116e2848260208601611656565b91505092915050565b5f80fd5b5f67ffffffffffffffff821115611709576117086115af565b5b61171282611543565b9050602081019050919050565b828183375f83830152505050565b5f61173f61173a846116ef565b61160d565b90508281526020810184848401111561175b5761175a6116eb565b5b61176684828561171f565b509392505050565b5f82601f830112611782576117816115ab565b5b813561179284826020860161172d565b91505092915050565b5f805f805f60a086880312156117b4576117b3611328565b5b5f6117c188828901611376565b95505060206117d288828901611376565b945050604086013567ffffffffffffffff8111156117f3576117f261132c565b5b6117ff888289016116be565b935050606086013567ffffffffffffffff8111156118205761181f61132c565b5b61182c888289016116be565b925050608086013567ffffffffffffffff81111561184d5761184c61132c565b5b6118598882890161176e565b9150509295509295909350565b5f67ffffffffffffffff8211156118805761187f6115af565b5b602082029050602081019050919050565b5f6118a361189e84611866565b61160d565b905080838252602082019050602084028301858111156118c6576118c5611652565b5b835b818110156118ef57806118db8882611376565b8452602084019350506020810190506118c8565b5050509392505050565b5f82601f83011261190d5761190c6115ab565b5b813561191d848260208601611891565b91505092915050565b5f806040838503121561193c5761193b611328565b5b5f83013567ffffffffffffffff8111156119595761195861132c565b5b611965858286016118f9565b925050602083013567ffffffffffffffff8111156119865761198561132c565b5b611992858286016116be565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6119ce8161138a565b82525050565b5f6119df83836119c5565b60208301905092915050565b5f602082019050919050565b5f611a018261199c565b611a0b81856119a6565b9350611a16836119b6565b805f5b83811015611a46578151611a2d88826119d4565b9750611a38836119eb565b925050600181019050611a19565b5085935050505092915050565b5f6020820190508181035f830152611a6b81846119f7565b905092915050565b5f805f8060808587031215611a8b57611a8a611328565b5b5f611a9887828801611376565b9450506020611aa9878288016113a9565b9350506040611aba878288016113a9565b925050606085013567ffffffffffffffff811115611adb57611ada61132c565b5b611ae78782880161176e565b91505092959194509250565b611afc816114a3565b8114611b06575f80fd5b50565b5f81359050611b1781611af3565b92915050565b5f8060408385031215611b3357611b32611328565b5b5f611b4085828601611376565b9250506020611b5185828601611b09565b9150509250929050565b5f8060408385031215611b7157611b70611328565b5b5f611b7e85828601611376565b9250506020611b8f85828601611376565b9150509250929050565b5f805f805f60a08688031215611bb257611bb1611328565b5b5f611bbf88828901611376565b9550506020611bd088828901611376565b9450506040611be1888289016113a9565b9350506060611bf2888289016113a9565b925050608086013567ffffffffffffffff811115611c1357611c1261132c565b5b611c1f8882890161176e565b9150509295509295909350565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611c7057607f821691505b602082108103611c8357611c82611c2c565b5b50919050565b611c928161134f565b82525050565b5f604082019050611cab5f830185611c89565b611cb86020830184611c89565b9392505050565b5f604082019050611cd25f8301856113fb565b611cdf60208301846113fb565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f602082019050611d265f830184611c89565b92915050565b5f608082019050611d3f5f830187611c89565b611d4c60208301866113fb565b611d5960408301856113fb565b611d6660608301846113fb565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611da68261138a565b9150611db18361138a565b9250828201905080821115611dc957611dc8611d6f565b5b92915050565b5f6040820190508181035f830152611de781856119f7565b90508181036020830152611dfb81846119f7565b90509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f611e2882611e04565b611e328185611e0e565b9350611e4281856020860161151b565b611e4b81611543565b840191505092915050565b5f60a082019050611e695f830188611c89565b611e766020830187611c89565b611e8360408301866113fb565b611e9060608301856113fb565b8181036080830152611ea28184611e1e565b90509695505050505050565b5f81519050611ebc8161144e565b92915050565b5f60208284031215611ed757611ed6611328565b5b5f611ee484828501611eae565b91505092915050565b5f60a082019050611f005f830188611c89565b611f0d6020830187611c89565b8181036040830152611f1f81866119f7565b90508181036060830152611f3381856119f7565b90508181036080830152611f478184611e1e565b9050969550505050505056fea26469706673582212203835581c6344b12728c44fa4d9e912cd60e64012c1b772bb703d1c36825c16fd64736f6c63430008180033"; -pub const NFT_SWAP_CONTRACT_BYTES: &str = "60a060405234801562000010575f80fd5b50604051620055a2380380620055a2833981810160405281019062000036919062000147565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200009e90620001fb565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506200021b565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200011182620000e6565b9050919050565b620001238162000105565b81146200012e575f80fd5b50565b5f81519050620001418162000118565b92915050565b5f602082840312156200015f576200015e620000e2565b5b5f6200016e8482850162000131565b91505092915050565b5f82825260208201905092915050565b7f66656541646472657373206d757374206e6f74206265207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f620001e360238362000177565b9150620001f08262000187565b604082019050919050565b5f6020820190508181035f8301526200021481620001d5565b9050919050565b608051615360620002425f395f8181612aef01528181612b8a0152612f4801526153605ff3fe608060405260043610610113575f3560e01c80639b4603f21161009f578063cc90c19911610063578063cc90c1991461038e578063d6a71eb4146103b6578063e06cf966146103de578063efccb9eb14610408578063f23a6e611461044657610113565b80639b4603f2146102be578063b27e46fb146102da578063bc197c8114610302578063c8d9009b1461033e578063c92cd12d1461036657610113565b8063150b7a02116100e6578063150b7a02146101cb5780633e6af5f21461020757806346b95ac71461022f57806365e266171461026e5780636e6bf6d21461029657610113565b806301ffc9a71461011757806305ec158d146101535780630f235fce1461017b578063146e5b24146101a3575b5f80fd5b348015610122575f80fd5b5061013d6004803603810190610138919061386f565b610482565b60405161014a91906138b4565b60405180910390f35b34801561015e575f80fd5b506101796004803603810190610174919061398d565b610563565b005b348015610186575f80fd5b506101a1600480360381019061019c9190613a2a565b610823565b005b3480156101ae575f80fd5b506101c960048036038101906101c49190613ab3565b610add565b005b3480156101d6575f80fd5b506101f160048036038101906101ec9190613bb1565b610cc3565b6040516101fe9190613c44565b60405180910390f35b348015610212575f80fd5b5061022d60048036038101906102289190613ab3565b611112565b005b34801561023a575f80fd5b5061025560048036038101906102509190613c5d565b611423565b6040516102659493929190613d53565b60405180910390f35b348015610279575f80fd5b50610294600480360381019061028f9190613ab3565b611485565b005b3480156102a1575f80fd5b506102bc60048036038101906102b79190613a2a565b6118e9565b005b6102d860048036038101906102d39190613dc0565b611ba4565b005b3480156102e5575f80fd5b5061030060048036038101906102fb919061398d565b611eda565b005b34801561030d575f80fd5b5061032860048036038101906103239190613eb2565b612199565b6040516103359190613c44565b60405180910390f35b348015610349575f80fd5b50610364600480360381019061035f9190613a2a565b6121d5565b005b348015610371575f80fd5b5061038c6004803603810190610387919061398d565b6124fe565b005b348015610399575f80fd5b506103b460048036038101906103af9190613ab3565b61282c565b005b3480156103c1575f80fd5b506103dc60048036038101906103d79190613f89565b612bdc565b005b3480156103e9575f80fd5b506103f2612f46565b6040516103ff919061405c565b60405180910390f35b348015610413575f80fd5b5061042e60048036038101906104299190613c5d565b612f6a565b60405161043d939291906140bb565b60405180910390f35b348015610451575f80fd5b5061046c600480360381019061046791906140f0565b612fb6565b6040516104799190613c44565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061054c57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061055c575061055b8261344a565b5b9050919050565b6001600381111561057757610576613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff1660038111156105a9576105a8613ce0565b5b146105e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e090614206565b60405180910390fd5b5f600387336002896040516020016106019190614244565b60405160208183030381529060405260405161061d91906142ca565b602060405180830381855afa158015610638573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065b91906142f4565b888888886040516020016106759796959493929190614384565b60405160208183030381529060405260405161069191906142ca565b602060405180830381855afa1580156106ac573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610736576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072d9061444e565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561076c5761076b613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd73886040516107a0919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016107eb94939291906144d6565b5f604051808303815f87803b158015610802575f80fd5b505af1158015610814573d5f803e3d5ffd5b50505050505050505050505050565b6001600381111561083757610836613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561086957610868613ce0565b5b146108a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a090614206565b60405180910390fd5b5f60038633878787876040516020016108c79695949392919061452c565b6040516020818303038152906040526040516108e391906142ca565b602060405180830381855afa1580156108fe573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097f9061444e565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156109f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ea9061460b565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610a2957610a28613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907287604051610a5d919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610aa693929190614629565b5f604051808303815f87803b158015610abd575f80fd5b505af1158015610acf573d5f803e3d5ffd5b505050505050505050505050565b60016004811115610af157610af0613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115610b2457610b23613ce0565b5b14610b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5b90614206565b60405180910390fd5b5f600387878733888888604051602001610b84979695949392919061465e565b604051602081830303815290604052604051610ba091906142ca565b602060405180830381855afa158015610bbb573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610c46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3d9061444e565b60405180910390fd5b600260015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610c7d57610c7c613ce0565b5b02179055507f9c45e43e2ef051f70491ffd5221bf02ab37e1324128714ef9610df5f24fc9fb588604051610cb1919061447b565b60405180910390a15050505050505050565b5f808383810190610cd49190614807565b90505f6003811115610ce957610ce8613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff166003811115610d1e57610d1d613ce0565b5b14610d5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d55906148a2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603610dd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc79061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610e42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3990614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610eb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eab90614a00565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610f22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1990614a68565b60405180910390fd5b610f2f81602001516134b3565b15610f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6690614ad0565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610f9d9695949392919061452c565b604051602081830303815290604052604051610fb991906142ca565b602060405180830381855afa158015610fd4573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561102457611023613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156110bb576110ba613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f01516040516110f5919061447b565b60405180910390a163150b7a0260e01b9250505095945050505050565b6001600481111561112657611125613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561115957611158613ce0565b5b14611199576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119090614206565b60405180910390fd5b5f6003878787336002896040516020016111b39190614244565b6040516020818303038152906040526040516111cf91906142ca565b602060405180830381855afa1580156111ea573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061120d91906142f4565b8888604051602001611225979695949392919061465e565b60405160208183030381529060405260405161124191906142ca565b602060405180830381855afa15801561125c573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146112e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112de9061444e565b60405180910390fd5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff0219169083600481111561131e5761131d613ce0565b5b02179055507f45169a52eef651b20a81474b50b8a5d83225225fcd097ef3cf7952d9ab304f278885604051611354929190614aee565b60405180910390a15f86886113699190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113e7573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156113e1573d5f803e3d5ffd5b50611418565b5f83905061141633838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b6001602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900463ffffffff1690805f01601c9054906101000a900460ff16905084565b6001600481111561149957611498613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff1660048111156114cc576114cb613ce0565b5b148061151c5750600260048111156114e7576114e6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561151a57611519613ce0565b5b145b61155b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155290614be5565b60405180910390fd5b5f60038787873388888860405160200161157b979695949392919061465e565b60405160208183030381529060405260405161159791906142ca565b602060405180830381855afa1580156115b2573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461163d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116349061444e565b60405180910390fd5b6002600481111561165157611650613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561168457611683613ce0565b5b036116f65760015f8981526020019081526020015f205f0160189054906101000a900463ffffffff1663ffffffff164210156116f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ec9061460b565b60405180910390fd5b5b6001600481111561170a57611709613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561173d5761173c613ce0565b5b036117af5760015f8981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156117ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a590614c73565b60405180910390fd5b5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156117e6576117e5613ce0565b5b02179055507fbdd7a4be6d82798a500b59077706b12d3f45acf5504828919f92501307b2b9538860405161181a919061447b565b60405180910390a15f868861182f9190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118ad573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156118a7573d5f803e3d5ffd5b506118de565b5f8390506118dc33838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b600160038111156118fd576118fc613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561192f5761192e613ce0565b5b1461196f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196690614206565b60405180910390fd5b5f600386336002886040516020016119879190614244565b6040516020818303038152906040526040516119a391906142ca565b602060405180830381855afa1580156119be573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906119e191906142f4565b8787876040516020016119f99695949392919061452c565b604051602081830303815290604052604051611a1591906142ca565b602060405180830381855afa158015611a30573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611aba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab19061444e565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115611af057611aef613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051611b24919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401611b6d93929190614629565b5f604051808303815f87803b158015611b84575f80fd5b505af1158015611b96573d5f803e3d5ffd5b505050505050505050505050565b5f6004811115611bb757611bb6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115611bea57611be9613ce0565b5b14611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2190614d01565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611c98576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8f90614d8f565b60405180910390fd5b5f3411611cda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd190614e1d565b60405180910390fd5b853411611d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1390614eab565b60405180910390fd5b5f60038734611d2b9190614ec9565b88883389895f604051602001611d47979695949392919061465e565b604051602081830303815290604052604051611d6391906142ca565b602060405180830381855afa158015611d7e573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115611dd657611dd5613ce0565b5b81525060015f8a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115611e9157611e90613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd93588604051611ec8919061447b565b60405180910390a15050505050505050565b60016003811115611eee57611eed613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115611f2057611f1f613ce0565b5b14611f60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5790614206565b60405180910390fd5b5f600387338888888888604051602001611f809796959493929190614384565b604051602081830303815290604052604051611f9c91906142ca565b602060405180830381855afa158015611fb7573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612041576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120389061444e565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156120ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a39061460b565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156120e2576120e1613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907288604051612116919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161216194939291906144d6565b5f604051808303815f87803b158015612178575f80fd5b505af115801561218a573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121cc90614f46565b60405180910390fd5b600160038111156121e9576121e8613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561221b5761221a613ce0565b5b1461225b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161225290614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c090614fae565b60405180910390fd5b5f60033387876002886040516020016122e29190614244565b6040516020818303038152906040526040516122fe91906142ca565b602060405180830381855afa158015612319573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061233c91906142f4565b87876040516020016123539695949392919061452c565b60405160208183030381529060405260405161236f91906142ca565b602060405180830381855afa15801561238a573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612414576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240b9061444e565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561244a57612449613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161247e919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016124c793929190614629565b5f604051808303815f87803b1580156124de575f80fd5b505af11580156124f0573d5f803e3d5ffd5b505050505050505050505050565b6001600381111561251257612511613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561254457612543613ce0565b5b14612584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257b90614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146125f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125e990614fae565b60405180910390fd5b5f600333888860028960405160200161260b9190614244565b60405160208183030381529060405260405161262791906142ca565b602060405180830381855afa158015612642573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061266591906142f4565b88888860405160200161267e9796959493929190614384565b60405160208183030381529060405260405161269a91906142ca565b602060405180830381855afa1580156126b5573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461273f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127369061444e565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561277557612774613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0886040516127a9919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016127f494939291906144d6565b5f604051808303815f87803b15801561280b575f80fd5b505af115801561281d573d5f803e3d5ffd5b50505050505050505050505050565b600260048111156128405761283f613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561287357612872613ce0565b5b146128b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128aa9061503c565b60405180910390fd5b5f600387873388886002896040516020016128ce9190614244565b6040516020818303038152906040526040516128ea91906142ca565b602060405180830381855afa158015612905573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061292891906142f4565b8860405160200161293f979695949392919061465e565b60405160208183030381529060405260405161295b91906142ca565b602060405180830381855afa158015612976573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612a01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129f89061444e565b60405180910390fd5b600360015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115612a3857612a37613ce0565b5b02179055507f0d0da0df275f85bed3a5fe7ae79f3559341a3f9ccd8e010133438135bda00a878884604051612a6e929190614aee565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612b56573373ffffffffffffffffffffffffffffffffffffffff166108fc8890811502906040515f60405180830381858888f19350505050158015612aec573d5f803e3d5ffd5b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f19350505050158015612b50573d5f803e3d5ffd5b50612bd2565b5f829050612b8533898373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b612bd07f0000000000000000000000000000000000000000000000000000000000000000888373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b5050505050505050565b5f6004811115612bef57612bee613ce0565b5b60015f8b81526020019081526020015f205f01601c9054906101000a900460ff166004811115612c2257612c21613ce0565b5b14612c62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c59906150ca565b60405180910390fd5b5f8811612ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c9b90615132565b60405180910390fd5b5f8711612ce6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cdd9061519a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612d54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d4b90614d8f565b60405180910390fd5b5f60038989883389898d604051602001612d74979695949392919061465e565b604051602081830303815290604052604051612d9091906142ca565b602060405180830381855afa158015612dab573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115612e0357612e02613ce0565b5b81525060015f8c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115612ebe57612ebd613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358a604051612ef5919061447b565b60405180910390a15f879050612f3933308b8d612f129190614b42565b8473ffffffffffffffffffffffffffffffffffffffff16613543909392919063ffffffff16565b5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f808383810190612fc79190614807565b90505f6003811115612fdc57612fdb613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff16600381111561301157613010613ce0565b5b14613051576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161304890615228565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff16036130c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130ba9061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161312c90614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146131a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161319e90614a00565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614613215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161320c90614a68565b60405180910390fd5b5f8511613257576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161324e90615290565b60405180910390fd5b61326481602001516134b3565b156132a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161329b90614ad0565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c6040516020016132d49796959493929190614384565b6040516020818303038152906040526040516132f091906142ca565b602060405180830381855afa15801561330b573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561335b5761335a613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156133f2576133f1613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f015160405161342c919061447b565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b61353e838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85856040516024016134f79291906152ae565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b505050565b6135bf848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161357893929190614629565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b50505050565b5f6135ef828473ffffffffffffffffffffffffffffffffffffffff1661365a90919063ffffffff16565b90505f81511415801561361357508080602001905181019061361191906152ff565b155b1561365557826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161364c919061405c565b60405180910390fd5b505050565b606061366783835f61366f565b905092915050565b6060814710156136b657306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016136ad919061405c565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516136de91906142ca565b5f6040518083038185875af1925050503d805f8114613718576040519150601f19603f3d011682016040523d82523d5f602084013e61371d565b606091505b509150915061372d868383613738565b925050509392505050565b60608261374d57613748826137c5565b6137bd565b5f825114801561377357505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156137b557836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016137ac919061405c565b60405180910390fd5b8190506137be565b5b9392505050565b5f815111156137d75780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61384e8161381a565b8114613858575f80fd5b50565b5f8135905061386981613845565b92915050565b5f6020828403121561388457613883613812565b5b5f6138918482850161385b565b91505092915050565b5f8115159050919050565b6138ae8161389a565b82525050565b5f6020820190506138c75f8301846138a5565b92915050565b5f819050919050565b6138df816138cd565b81146138e9575f80fd5b50565b5f813590506138fa816138d6565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61392982613900565b9050919050565b6139398161391f565b8114613943575f80fd5b50565b5f8135905061395481613930565b92915050565b5f819050919050565b61396c8161395a565b8114613976575f80fd5b50565b5f8135905061398781613963565b92915050565b5f805f805f805f60e0888a0312156139a8576139a7613812565b5b5f6139b58a828b016138ec565b97505060206139c68a828b01613946565b96505060406139d78a828b016138ec565b95505060606139e88a828b016138ec565b94505060806139f98a828b01613946565b93505060a0613a0a8a828b01613979565b92505060c0613a1b8a828b01613979565b91505092959891949750929550565b5f805f805f8060c08789031215613a4457613a43613812565b5b5f613a5189828a016138ec565b9650506020613a6289828a01613946565b9550506040613a7389828a016138ec565b9450506060613a8489828a016138ec565b9350506080613a9589828a01613946565b92505060a0613aa689828a01613979565b9150509295509295509295565b5f805f805f805f60e0888a031215613ace57613acd613812565b5b5f613adb8a828b016138ec565b9750506020613aec8a828b01613979565b9650506040613afd8a828b01613979565b9550506060613b0e8a828b01613946565b9450506080613b1f8a828b016138ec565b93505060a0613b308a828b016138ec565b92505060c0613b418a828b01613946565b91505092959891949750929550565b5f80fd5b5f80fd5b5f80fd5b5f8083601f840112613b7157613b70613b50565b5b8235905067ffffffffffffffff811115613b8e57613b8d613b54565b5b602083019150836001820283011115613baa57613ba9613b58565b5b9250929050565b5f805f805f60808688031215613bca57613bc9613812565b5b5f613bd788828901613946565b9550506020613be888828901613946565b9450506040613bf988828901613979565b935050606086013567ffffffffffffffff811115613c1a57613c19613816565b5b613c2688828901613b5c565b92509250509295509295909350565b613c3e8161381a565b82525050565b5f602082019050613c575f830184613c35565b92915050565b5f60208284031215613c7257613c71613812565b5b5f613c7f848285016138ec565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b613cbc81613c88565b82525050565b5f63ffffffff82169050919050565b613cda81613cc2565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60058110613d1e57613d1d613ce0565b5b50565b5f819050613d2e82613d0d565b919050565b5f613d3d82613d21565b9050919050565b613d4d81613d33565b82525050565b5f608082019050613d665f830187613cb3565b613d736020830186613cd1565b613d806040830185613cd1565b613d8d6060830184613d44565b95945050505050565b613d9f81613cc2565b8114613da9575f80fd5b50565b5f81359050613dba81613d96565b92915050565b5f805f805f805f60e0888a031215613ddb57613dda613812565b5b5f613de88a828b016138ec565b9750506020613df98a828b01613979565b9650506040613e0a8a828b01613946565b9550506060613e1b8a828b016138ec565b9450506080613e2c8a828b016138ec565b93505060a0613e3d8a828b01613dac565b92505060c0613e4e8a828b01613dac565b91505092959891949750929550565b5f8083601f840112613e7257613e71613b50565b5b8235905067ffffffffffffffff811115613e8f57613e8e613b54565b5b602083019150836020820283011115613eab57613eaa613b58565b5b9250929050565b5f805f805f805f8060a0898b031215613ece57613ecd613812565b5b5f613edb8b828c01613946565b9850506020613eec8b828c01613946565b975050604089013567ffffffffffffffff811115613f0d57613f0c613816565b5b613f198b828c01613e5d565b9650965050606089013567ffffffffffffffff811115613f3c57613f3b613816565b5b613f488b828c01613e5d565b9450945050608089013567ffffffffffffffff811115613f6b57613f6a613816565b5b613f778b828c01613b5c565b92509250509295985092959890939650565b5f805f805f805f805f6101208a8c031215613fa757613fa6613812565b5b5f613fb48c828d016138ec565b9950506020613fc58c828d01613979565b9850506040613fd68c828d01613979565b9750506060613fe78c828d01613946565b9650506080613ff88c828d01613946565b95505060a06140098c828d016138ec565b94505060c061401a8c828d016138ec565b93505060e061402b8c828d01613dac565b92505061010061403d8c828d01613dac565b9150509295985092959850929598565b6140568161391f565b82525050565b5f60208201905061406f5f83018461404d565b92915050565b6004811061408657614085613ce0565b5b50565b5f81905061409682614075565b919050565b5f6140a582614089565b9050919050565b6140b58161409b565b82525050565b5f6060820190506140ce5f830186613cb3565b6140db6020830185613cd1565b6140e860408301846140ac565b949350505050565b5f805f805f8060a0878903121561410a57614109613812565b5b5f61411789828a01613946565b965050602061412889828a01613946565b955050604061413989828a01613979565b945050606061414a89828a01613979565b935050608087013567ffffffffffffffff81111561416b5761416a613816565b5b61417789828a01613b5c565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f6141f0602a83614186565b91506141fb82614196565b604082019050919050565b5f6020820190508181035f83015261421d816141e4565b9050919050565b5f819050919050565b61423e614239826138cd565b614224565b82525050565b5f61424f828461422d565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b5f5b8381101561428f578082015181840152602081019050614274565b5f8484015250505050565b5f6142a48261425e565b6142ae8185614268565b93506142be818560208601614272565b80840191505092915050565b5f6142d5828461429a565b915081905092915050565b5f815190506142ee816138d6565b92915050565b5f6020828403121561430957614308613812565b5b5f614316848285016142e0565b91505092915050565b5f8160601b9050919050565b5f6143358261431f565b9050919050565b5f6143468261432b565b9050919050565b61435e6143598261391f565b61433c565b82525050565b5f819050919050565b61437e6143798261395a565b614364565b82525050565b5f61438f828a61434d565b60148201915061439f828961434d565b6014820191506143af828861422d565b6020820191506143bf828761422d565b6020820191506143cf828661434d565b6014820191506143df828561436d565b6020820191506143ef828461436d565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f614438601383614186565b915061444382614404565b602082019050919050565b5f6020820190508181035f8301526144658161442c565b9050919050565b614475816138cd565b82525050565b5f60208201905061448e5f83018461446c565b92915050565b61449d8161395a565b82525050565b5f82825260208201905092915050565b50565b5f6144c15f836144a3565b91506144cc826144b3565b5f82019050919050565b5f60a0820190506144e95f83018761404d565b6144f6602083018661404d565b6145036040830185614494565b6145106060830184614494565b8181036080830152614521816144b6565b905095945050505050565b5f614537828961434d565b601482019150614547828861434d565b601482019150614557828761422d565b602082019150614567828661422d565b602082019150614577828561434d565b601482019150614587828461436d565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f6145f5603883614186565b91506146008261459b565b604082019050919050565b5f6020820190508181035f830152614622816145e9565b9050919050565b5f60608201905061463c5f83018661404d565b614649602083018561404d565b6146566040830184614494565b949350505050565b5f614669828a61436d565b602082019150614679828961436d565b602082019150614689828861434d565b601482019150614699828761434d565b6014820191506146a9828661422d565b6020820191506146b9828561422d565b6020820191506146c9828461434d565b60148201915081905098975050505050505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b614728826146e2565b810181811067ffffffffffffffff82111715614747576147466146f2565b5b80604052505050565b5f614759613809565b9050614765828261471f565b919050565b5f60c0828403121561477f5761477e6146de565b5b61478960c0614750565b90505f614798848285016138ec565b5f8301525060206147ab84828501613946565b60208301525060406147bf84828501613946565b60408301525060606147d3848285016138ec565b60608301525060806147e7848285016138ec565b60808301525060a06147fb84828501613dac565b60a08301525092915050565b5f60c0828403121561481c5761481b613812565b5b5f6148298482850161476a565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f61488c602a83614186565b915061489782614832565b604082019050919050565b5f6020820190508181035f8301526148b981614880565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f6148f4601e83614186565b91506148ff826148c0565b602082019050919050565b5f6020820190508181035f830152614921816148e8565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f61495c601e83614186565b915061496782614928565b602082019050919050565b5f6020820190508181035f83015261498981614950565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f6149ea602383614186565b91506149f582614990565b604082019050919050565b5f6020820190508181035f830152614a17816149de565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f614a52601b83614186565b9150614a5d82614a1e565b602082019050919050565b5f6020820190508181035f830152614a7f81614a46565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f614aba601a83614186565b9150614ac582614a86565b602082019050919050565b5f6020820190508181035f830152614ae781614aae565b9050919050565b5f604082019050614b015f83018561446c565b614b0e602083018461446c565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614b4c8261395a565b9150614b578361395a565b9250828201905080821115614b6f57614b6e614b15565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e74206f722054616b6572417070726f7665640000000000602082015250565b5f614bcf603b83614186565b9150614bda82614b75565b604082019050919050565b5f6020820190508181035f830152614bfc81614bc3565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e74207072652d617070726f7665206c6f636b2074696d65000000602082015250565b5f614c5d603d83614186565b9150614c6882614c03565b604082019050919050565b5f6020820190508181035f830152614c8a81614c51565b9050919050565b7f54616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f614ceb602483614186565b9150614cf682614c91565b604082019050919050565b5f6020820190508181035f830152614d1881614cdf565b9050919050565b7f5265636569766572206d757374206e6f74206265207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f614d79602183614186565b9150614d8482614d1f565b604082019050919050565b5f6020820190508181035f830152614da681614d6d565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f614e07602383614186565b9150614e1282614dad565b604082019050919050565b5f6020820190508181035f830152614e3481614dfb565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e20645f8201527f6578206665650000000000000000000000000000000000000000000000000000602082015250565b5f614e95602683614186565b9150614ea082614e3b565b604082019050919050565b5f6020820190508181035f830152614ec281614e89565b9050919050565b5f614ed38261395a565b9150614ede8361395a565b9250828203905081811115614ef657614ef5614b15565b5b92915050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f614f30601d83614186565b9150614f3b82614efc565b602082019050919050565b5f6020820190508181035f830152614f5d81614f24565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f614f98601583614186565b9150614fa382614f64565b602082019050919050565b5f6020820190508181035f830152614fc581614f8c565b9050919050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520545f8201527f616b6572417070726f7665640000000000000000000000000000000000000000602082015250565b5f615026602c83614186565b915061503182614fcc565b604082019050919050565b5f6020820190508181035f8301526150538161501a565b9050919050565b7f4552433230207632207061796d656e7420697320616c726561647920696e69745f8201527f69616c697a656400000000000000000000000000000000000000000000000000602082015250565b5f6150b4602783614186565b91506150bf8261505a565b604082019050919050565b5f6020820190508181035f8301526150e1816150a8565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f61511c601783614186565b9150615127826150e8565b602082019050919050565b5f6020820190508181035f83015261514981615110565b9050919050565b7f44657820666565206d757374206e6f74206265207a65726f00000000000000005f82015250565b5f615184601883614186565b915061518f82615150565b602082019050919050565b5f6020820190508181035f8301526151b181615178565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f615212602b83614186565b915061521d826151b8565b604082019050919050565b5f6020820190508181035f83015261523f81615206565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f61527a601c83614186565b915061528582615246565b602082019050919050565b5f6020820190508181035f8301526152a78161526e565b9050919050565b5f6040820190506152c15f83018561404d565b6152ce6020830184614494565b9392505050565b6152de8161389a565b81146152e8575f80fd5b50565b5f815190506152f9816152d5565b92915050565b5f6020828403121561531457615313613812565b5b5f615321848285016152eb565b9150509291505056fea26469706673582212200d86b0f6898fb823c55626c3b02a7098bc8622606b092e0f458df6c86ce2967864736f6c63430008180033"; +pub const ERC20_TOKEN_BYTES: &str = include_str!("../../../mm2_test_helpers/contract_bytes/erc20_token_bytes"); +pub const SWAP_CONTRACT_BYTES: &str = include_str!("../../../mm2_test_helpers/contract_bytes/swap_contract_bytes"); +pub const WATCHERS_SWAP_CONTRACT_BYTES: &str = + include_str!("../../../mm2_test_helpers/contract_bytes/watchers_swap_contract_bytes"); +pub const ERC721_TEST_TOKEN_BYTES: &str = + include_str!("../../../mm2_test_helpers/contract_bytes/erc721_test_token_bytes"); +pub const ERC1155_TEST_TOKEN_BYTES: &str = + include_str!("../../../mm2_test_helpers/contract_bytes/erc1155_test_token_bytes"); +pub const NFT_SWAP_CONTRACT_BYTES: &str = + include_str!("../../../mm2_test_helpers/contract_bytes/nft_swap_contract_bytes"); /// https://github.com/KomodoPlatform/etomic-swap/blob/006e6fd52334530f23624a2139d0eb5299c4cd10/contracts/EtomicSwapMakerNftV2Test.sol -pub const NFT_MAKER_SWAP_V2_BYTES: &str = "6080604052348015600e575f80fd5b506131fa8061001c5f395ff3fe608060405234801561000f575f80fd5b50600436106100cd575f3560e01c8063bc197c811161008a578063eb4ab61211610064578063eb4ab61214610209578063efccb9eb14610225578063f0e9fcd114610257578063f23a6e6114610273576100cd565b8063bc197c81146101a1578063c8d9009b146101d1578063c92cd12d146101ed576100cd565b806301ffc9a7146100d157806305ec158d146101015780630f235fce1461011d578063150b7a02146101395780636e6bf6d214610169578063b27e46fb14610185575b5f80fd5b6100eb60048036038101906100e69190612005565b6102a3565b6040516100f8919061204a565b60405180910390f35b61011b60048036038101906101169190612123565b610384565b005b610137600480360381019061013291906121c0565b610644565b005b610153600480360381019061014e91906122aa565b6108fe565b604051610160919061233d565b60405180910390f35b610183600480360381019061017e91906121c0565b610d4d565b005b61019f600480360381019061019a9190612123565b611008565b005b6101bb60048036038101906101b691906123ab565b6112c7565b6040516101c8919061233d565b60405180910390f35b6101eb60048036038101906101e691906121c0565b611303565b005b61020760048036038101906102029190612123565b61162c565b005b610223600480360381019061021e9190612482565b61195a565b005b61023f600480360381019061023a91906124e6565b6119d1565b60405161024e939291906125dc565b60405180910390f35b610271600480360381019061026c9190612611565b611a1d565b005b61028d60048036038101906102889190612661565b611a91565b60405161029a919061233d565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061036d57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061037d575061037c82611f25565b5b9050919050565b6001600381111561039857610397612569565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff1660038111156103ca576103c9612569565b5b1461040a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161040190612777565b60405180910390fd5b5f6003873360028960405160200161042291906127b5565b60405160208183030381529060405260405161043e9190612821565b602060405180830381855afa158015610459573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061047c919061284b565b8888888860405160200161049697969594939291906128db565b6040516020818303038152906040526040516104b29190612821565b602060405180830381855afa1580156104cd573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610557576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161054e906129a5565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561058d5761058c612569565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd73886040516105c191906129d2565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161060c9493929190612a3c565b5f604051808303815f87803b158015610623575f80fd5b505af1158015610635573d5f803e3d5ffd5b50505050505050505050505050565b6001600381111561065857610657612569565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561068a57610689612569565b5b146106ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c190612777565b60405180910390fd5b5f60038633878787876040516020016106e896959493929190612a92565b6040516020818303038152906040526040516107049190612821565b602060405180830381855afa15801561071f573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146107a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107a0906129a5565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610814576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161080b90612b71565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561084a57610849612569565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad192190728760405161087e91906129d2565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016108c793929190612b8f565b5f604051808303815f87803b1580156108de575f80fd5b505af11580156108f0573d5f803e3d5ffd5b505050505050505050505050565b5f80838381019061090f9190612d17565b90505f600381111561092457610923612569565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff16600381111561095957610958612569565b5b14610999576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099090612db2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603610a0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0290612e1a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610a7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7490612e82565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610aef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae690612f10565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610b5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5490612f78565b60405180910390fd5b610b6a8160200151611f8e565b15610baa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba190612fe0565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610bd896959493929190612a92565b604051602081830303815290604052604051610bf49190612821565b602060405180830381855afa158015610c0f573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115610c5f57610c5e612569565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115610cf657610cf5612569565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051610d3091906129d2565b60405180910390a163150b7a0260e01b9250505095945050505050565b60016003811115610d6157610d60612569565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff166003811115610d9357610d92612569565b5b14610dd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dca90612777565b60405180910390fd5b5f60038633600288604051602001610deb91906127b5565b604051602081830303815290604052604051610e079190612821565b602060405180830381855afa158015610e22573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610e45919061284b565b878787604051602001610e5d96959493929190612a92565b604051602081830303815290604052604051610e799190612821565b602060405180830381855afa158015610e94573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610f1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f15906129a5565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610f5457610f53612569565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051610f8891906129d2565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610fd193929190612b8f565b5f604051808303815f87803b158015610fe8575f80fd5b505af1158015610ffa573d5f803e3d5ffd5b505050505050505050505050565b6001600381111561101c5761101b612569565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561104e5761104d612569565b5b1461108e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108590612777565b60405180910390fd5b5f6003873388888888886040516020016110ae97969594939291906128db565b6040516020818303038152906040526040516110ca9190612821565b602060405180830381855afa1580156110e5573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461116f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611166906129a5565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156111da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d190612b71565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156112105761120f612569565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad192190728860405161124491906129d2565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161128f9493929190612a3c565b5f604051808303815f87803b1580156112a6575f80fd5b505af11580156112b8573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112fa90613048565b60405180910390fd5b6001600381111561131757611316612569565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561134957611348612569565b5b14611389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138090612777565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ee906130b0565b60405180910390fd5b5f600333878760028860405160200161141091906127b5565b60405160208183030381529060405260405161142c9190612821565b602060405180830381855afa158015611447573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061146a919061284b565b878760405160200161148196959493929190612a92565b60405160208183030381529060405260405161149d9190612821565b602060405180830381855afa1580156114b8573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611542576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611539906129a5565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561157857611577612569565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0876040516115ac91906129d2565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016115f593929190612b8f565b5f604051808303815f87803b15801561160c575f80fd5b505af115801561161e573d5f803e3d5ffd5b505050505050505050505050565b600160038111156116405761163f612569565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561167257611671612569565b5b146116b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a990612777565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611720576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611717906130b0565b60405180910390fd5b5f600333888860028960405160200161173991906127b5565b6040516020818303038152906040526040516117559190612821565b602060405180830381855afa158015611770573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190611793919061284b565b8888886040516020016117ac97969594939291906128db565b6040516020818303038152906040526040516117c89190612821565b602060405180830381855afa1580156117e3573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461186d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611864906129a5565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156118a3576118a2612569565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0886040516118d791906129d2565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016119229493929190612a3c565b5f604051808303815f87803b158015611939575f80fd5b505af115801561194b573d5f803e3d5ffd5b50505050505050505050505050565b5f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a308487876040518563ffffffff1660e01b815260040161199d9493929190612a3c565b5f604051808303815f87803b1580156119b4575f80fd5b505af11580156119c6573d5f803e3d5ffd5b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3084866040518463ffffffff1660e01b8152600401611a5e93929190612b8f565b5f604051808303815f87803b158015611a75575f80fd5b505af1158015611a87573d5f803e3d5ffd5b5050505050505050565b5f808383810190611aa29190612d17565b90505f6003811115611ab757611ab6612569565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff166003811115611aec57611aeb612569565b5b14611b2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b239061313e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603611b9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9590612e1a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603611c10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c0790612e82565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7990612f10565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614611cf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce790612f78565b60405180910390fd5b5f8511611d32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d29906131a6565b60405180910390fd5b611d3f8160200151611f8e565b15611d7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7690612fe0565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c604051602001611daf97969594939291906128db565b604051602081830303815290604052604051611dcb9190612821565b602060405180830381855afa158015611de6573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115611e3657611e35612569565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115611ecd57611ecc612569565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051611f0791906129d2565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611fe481611fb0565b8114611fee575f80fd5b50565b5f81359050611fff81611fdb565b92915050565b5f6020828403121561201a57612019611fa8565b5b5f61202784828501611ff1565b91505092915050565b5f8115159050919050565b61204481612030565b82525050565b5f60208201905061205d5f83018461203b565b92915050565b5f819050919050565b61207581612063565b811461207f575f80fd5b50565b5f813590506120908161206c565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6120bf82612096565b9050919050565b6120cf816120b5565b81146120d9575f80fd5b50565b5f813590506120ea816120c6565b92915050565b5f819050919050565b612102816120f0565b811461210c575f80fd5b50565b5f8135905061211d816120f9565b92915050565b5f805f805f805f60e0888a03121561213e5761213d611fa8565b5b5f61214b8a828b01612082565b975050602061215c8a828b016120dc565b965050604061216d8a828b01612082565b955050606061217e8a828b01612082565b945050608061218f8a828b016120dc565b93505060a06121a08a828b0161210f565b92505060c06121b18a828b0161210f565b91505092959891949750929550565b5f805f805f8060c087890312156121da576121d9611fa8565b5b5f6121e789828a01612082565b96505060206121f889828a016120dc565b955050604061220989828a01612082565b945050606061221a89828a01612082565b935050608061222b89828a016120dc565b92505060a061223c89828a0161210f565b9150509295509295509295565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261226a57612269612249565b5b8235905067ffffffffffffffff8111156122875761228661224d565b5b6020830191508360018202830111156122a3576122a2612251565b5b9250929050565b5f805f805f608086880312156122c3576122c2611fa8565b5b5f6122d0888289016120dc565b95505060206122e1888289016120dc565b94505060406122f28882890161210f565b935050606086013567ffffffffffffffff81111561231357612312611fac565b5b61231f88828901612255565b92509250509295509295909350565b61233781611fb0565b82525050565b5f6020820190506123505f83018461232e565b92915050565b5f8083601f84011261236b5761236a612249565b5b8235905067ffffffffffffffff8111156123885761238761224d565b5b6020830191508360208202830111156123a4576123a3612251565b5b9250929050565b5f805f805f805f8060a0898b0312156123c7576123c6611fa8565b5b5f6123d48b828c016120dc565b98505060206123e58b828c016120dc565b975050604089013567ffffffffffffffff81111561240657612405611fac565b5b6124128b828c01612356565b9650965050606089013567ffffffffffffffff81111561243557612434611fac565b5b6124418b828c01612356565b9450945050608089013567ffffffffffffffff81111561246457612463611fac565b5b6124708b828c01612255565b92509250509295985092959890939650565b5f805f806080858703121561249a57612499611fa8565b5b5f6124a7878288016120dc565b94505060206124b88782880161210f565b93505060406124c98782880161210f565b92505060606124da878288016120dc565b91505092959194509250565b5f602082840312156124fb576124fa611fa8565b5b5f61250884828501612082565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b61254581612511565b82525050565b5f63ffffffff82169050919050565b6125638161254b565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600481106125a7576125a6612569565b5b50565b5f8190506125b782612596565b919050565b5f6125c6826125aa565b9050919050565b6125d6816125bc565b82525050565b5f6060820190506125ef5f83018661253c565b6125fc602083018561255a565b61260960408301846125cd565b949350505050565b5f805f6060848603121561262857612627611fa8565b5b5f612635868287016120dc565b93505060206126468682870161210f565b9250506040612657868287016120dc565b9150509250925092565b5f805f805f8060a0878903121561267b5761267a611fa8565b5b5f61268889828a016120dc565b965050602061269989828a016120dc565b95505060406126aa89828a0161210f565b94505060606126bb89828a0161210f565b935050608087013567ffffffffffffffff8111156126dc576126db611fac565b5b6126e889828a01612255565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f612761602a836126f7565b915061276c82612707565b604082019050919050565b5f6020820190508181035f83015261278e81612755565b9050919050565b5f819050919050565b6127af6127aa82612063565b612795565b82525050565b5f6127c0828461279e565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6127fb826127cf565b61280581856127d9565b93506128158185602086016127e3565b80840191505092915050565b5f61282c82846127f1565b915081905092915050565b5f815190506128458161206c565b92915050565b5f602082840312156128605761285f611fa8565b5b5f61286d84828501612837565b91505092915050565b5f8160601b9050919050565b5f61288c82612876565b9050919050565b5f61289d82612882565b9050919050565b6128b56128b0826120b5565b612893565b82525050565b5f819050919050565b6128d56128d0826120f0565b6128bb565b82525050565b5f6128e6828a6128a4565b6014820191506128f682896128a4565b601482019150612906828861279e565b602082019150612916828761279e565b60208201915061292682866128a4565b60148201915061293682856128c4565b60208201915061294682846128c4565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f61298f6013836126f7565b915061299a8261295b565b602082019050919050565b5f6020820190508181035f8301526129bc81612983565b9050919050565b6129cc81612063565b82525050565b5f6020820190506129e55f8301846129c3565b92915050565b6129f4816120b5565b82525050565b612a03816120f0565b82525050565b5f82825260208201905092915050565b50565b5f612a275f83612a09565b9150612a3282612a19565b5f82019050919050565b5f60a082019050612a4f5f8301876129eb565b612a5c60208301866129eb565b612a6960408301856129fa565b612a7660608301846129fa565b8181036080830152612a8781612a1c565b905095945050505050565b5f612a9d82896128a4565b601482019150612aad82886128a4565b601482019150612abd828761279e565b602082019150612acd828661279e565b602082019150612add82856128a4565b601482019150612aed82846128c4565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f612b5b6038836126f7565b9150612b6682612b01565b604082019050919050565b5f6020820190508181035f830152612b8881612b4f565b9050919050565b5f606082019050612ba25f8301866129eb565b612baf60208301856129eb565b612bbc60408301846129fa565b949350505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612c0e82612bc8565b810181811067ffffffffffffffff82111715612c2d57612c2c612bd8565b5b80604052505050565b5f612c3f611f9f565b9050612c4b8282612c05565b919050565b612c598161254b565b8114612c63575f80fd5b50565b5f81359050612c7481612c50565b92915050565b5f60c08284031215612c8f57612c8e612bc4565b5b612c9960c0612c36565b90505f612ca884828501612082565b5f830152506020612cbb848285016120dc565b6020830152506040612ccf848285016120dc565b6040830152506060612ce384828501612082565b6060830152506080612cf784828501612082565b60808301525060a0612d0b84828501612c66565b60a08301525092915050565b5f60c08284031215612d2c57612d2b611fa8565b5b5f612d3984828501612c7a565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f612d9c602a836126f7565b9150612da782612d42565b604082019050919050565b5f6020820190508181035f830152612dc981612d90565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612e04601e836126f7565b9150612e0f82612dd0565b602082019050919050565b5f6020820190508181035f830152612e3181612df8565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612e6c601e836126f7565b9150612e7782612e38565b602082019050919050565b5f6020820190508181035f830152612e9981612e60565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f612efa6023836126f7565b9150612f0582612ea0565b604082019050919050565b5f6020820190508181035f830152612f2781612eee565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f612f62601b836126f7565b9150612f6d82612f2e565b602082019050919050565b5f6020820190508181035f830152612f8f81612f56565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f612fca601a836126f7565b9150612fd582612f96565b602082019050919050565b5f6020820190508181035f830152612ff781612fbe565b9050919050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f613032601d836126f7565b915061303d82612ffe565b602082019050919050565b5f6020820190508181035f83015261305f81613026565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f61309a6015836126f7565b91506130a582613066565b602082019050919050565b5f6020820190508181035f8301526130c78161308e565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f613128602b836126f7565b9150613133826130ce565b604082019050919050565b5f6020820190508181035f8301526131558161311c565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f613190601c836126f7565b915061319b8261315c565b602082019050919050565b5f6020820190508181035f8301526131bd81613184565b905091905056fea2646970667358221220c7235610f4c08b95d1e01bd31ff0b8b671c0f18c33212760a2ce3b09e6ad77e964736f6c63430008190033"; +pub const NFT_MAKER_SWAP_V2_BYTES: &str = + include_str!("../../../mm2_test_helpers/contract_bytes/nft_maker_swap_v2_bytes"); /// https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapMakerNftV2.sol -pub const MAKER_SWAP_V2_BYTES: &str = "6080604052348015600e575f80fd5b50611d9f8061001c5f395ff3fe608060405260043610610054575f3560e01c80631299a27a146100585780637466be601461008057806374a4788a1461009c5780639b949dee146100c4578063a53bc126146100ec578063efccb9eb14610114575b5f80fd5b348015610063575f80fd5b5061007e60048036038101906100799190611427565b610152565b005b61009a600480360381019061009591906114e9565b61044b565b005b3480156100a7575f80fd5b506100c260048036038101906100bd9190611427565b6106fc565b005b3480156100cf575f80fd5b506100ea60048036038101906100e59190611427565b6109f5565b005b3480156100f7575f80fd5b50610112600480360381019061010d9190611560565b610ced565b005b34801561011f575f80fd5b5061013a600480360381019061013591906115fd565b610fd2565b604051610149939291906116e4565b60405180910390f35b6001600381111561016657610165611671565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561019857610197611671565b5b146101d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101cf90611799565b60405180910390fd5b5f6003863387876002886040516020016101f291906117d7565b60405160208183030381529060405260405161020e9190611843565b602060405180830381855afa158015610229573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061024c919061186d565b87604051602001610262969594939291906118fd565b60405160208183030381529060405260405161027e9190611843565b602060405180830381855afa158015610299573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610323576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031a906119b6565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561035957610358611671565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161038d91906119e3565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610411573373ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f1935050505015801561040b573d5f803e3d5ffd5b50610442565b5f82905061044033888373ffffffffffffffffffffffffffffffffffffffff1661101e9092919063ffffffff16565b505b50505050505050565b5f600381111561045e5761045d611671565b5b5f808781526020019081526020015f205f0160189054906101000a900460ff1660038111156104905761048f611671565b5b146104d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c790611a6c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361053e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053590611ad4565b60405180910390fd5b5f3411610580576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057790611b62565b60405180910390fd5b5f600334863387875f60405160200161059e969594939291906118fd565b6040516020818303038152906040526040516105ba9190611843565b602060405180830381855afa1580156105d5573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018363ffffffff1681526020016001600381111561062157610620611671565b5b8152505f808881526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156106b5576106b4611671565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad866040516106ec91906119e3565b60405180910390a1505050505050565b600160038111156107105761070f611671565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561074257610741611671565b5b14610782576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161077990611799565b60405180910390fd5b5f600386863360028860405160200161079b91906117d7565b6040516020818303038152906040526040516107b79190611843565b602060405180830381855afa1580156107d2573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107f5919061186d565b878760405160200161080c969594939291906118fd565b6040516020818303038152906040526040516108289190611843565b602060405180830381855afa158015610843573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146108cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c4906119b6565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561090357610902611671565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd738760405161093791906119e3565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036109bb573373ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f193505050501580156109b5573d5f803e3d5ffd5b506109ec565b5f8290506109ea33888373ffffffffffffffffffffffffffffffffffffffff1661101e9092919063ffffffff16565b505b50505050505050565b60016003811115610a0957610a08611671565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff166003811115610a3b57610a3a611671565b5b14610a7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7290611799565b60405180910390fd5b5f6003868633878787604051602001610a99969594939291906118fd565b604051602081830303815290604052604051610ab59190611843565b602060405180830381855afa158015610ad0573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610b5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b51906119b6565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610bc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbc90611bf0565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610bfb57610bfa611671565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907287604051610c2f91906119e3565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610cb3573373ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f19350505050158015610cad573d5f803e3d5ffd5b50610ce4565b5f829050610ce233888373ffffffffffffffffffffffffffffffffffffffff1661101e9092919063ffffffff16565b505b50505050505050565b5f6003811115610d0057610cff611671565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115610d3257610d31611671565b5b14610d72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6990611a6c565b60405180910390fd5b5f8611610db4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dab90611c58565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610e22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1990611ad4565b60405180910390fd5b5f600387863387878b604051602001610e40969594939291906118fd565b604051602081830303815290604052604051610e5c9190611843565b602060405180830381855afa158015610e77573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018363ffffffff16815260200160016003811115610ec357610ec2611671565b5b8152505f808a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115610f5757610f56611671565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad88604051610f8e91906119e3565b60405180910390a15f869050610fc733308a8473ffffffffffffffffffffffffffffffffffffffff1661109d909392919063ffffffff16565b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b611098838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401611051929190611c94565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061111f565b505050565b611119848573ffffffffffffffffffffffffffffffffffffffff166323b872dd8686866040516024016110d293929190611cbb565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061111f565b50505050565b5f611149828473ffffffffffffffffffffffffffffffffffffffff166111b490919063ffffffff16565b90505f81511415801561116d57508080602001905181019061116b9190611d25565b155b156111af57826040517f5274afe70000000000000000000000000000000000000000000000000000000081526004016111a69190611d50565b60405180910390fd5b505050565b60606111c183835f6111c9565b905092915050565b60608147101561121057306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016112079190611d50565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516112389190611843565b5f6040518083038185875af1925050503d805f8114611272576040519150601f19603f3d011682016040523d82523d5f602084013e611277565b606091505b5091509150611287868383611292565b925050509392505050565b6060826112a7576112a28261131f565b611317565b5f82511480156112cd57505f8473ffffffffffffffffffffffffffffffffffffffff163b145b1561130f57836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016113069190611d50565b60405180910390fd5b819050611318565b5b9392505050565b5f815111156113315780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80fd5b5f819050919050565b61137981611367565b8114611383575f80fd5b50565b5f8135905061139481611370565b92915050565b5f819050919050565b6113ac8161139a565b81146113b6575f80fd5b50565b5f813590506113c7816113a3565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6113f6826113cd565b9050919050565b611406816113ec565b8114611410575f80fd5b50565b5f81359050611421816113fd565b92915050565b5f805f805f8060c0878903121561144157611440611363565b5b5f61144e89828a01611386565b965050602061145f89828a016113b9565b955050604061147089828a01611413565b945050606061148189828a01611386565b935050608061149289828a01611386565b92505060a06114a389828a01611413565b9150509295509295509295565b5f63ffffffff82169050919050565b6114c8816114b0565b81146114d2575f80fd5b50565b5f813590506114e3816114bf565b92915050565b5f805f805f60a0868803121561150257611501611363565b5b5f61150f88828901611386565b955050602061152088828901611413565b945050604061153188828901611386565b935050606061154288828901611386565b9250506080611553888289016114d5565b9150509295509295909350565b5f805f805f805f60e0888a03121561157b5761157a611363565b5b5f6115888a828b01611386565b97505060206115998a828b016113b9565b96505060406115aa8a828b01611413565b95505060606115bb8a828b01611413565b94505060806115cc8a828b01611386565b93505060a06115dd8a828b01611386565b92505060c06115ee8a828b016114d5565b91505092959891949750929550565b5f6020828403121561161257611611611363565b5b5f61161f84828501611386565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b61165c81611628565b82525050565b61166b816114b0565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600481106116af576116ae611671565b5b50565b5f8190506116bf8261169e565b919050565b5f6116ce826116b2565b9050919050565b6116de816116c4565b82525050565b5f6060820190506116f75f830186611653565b6117046020830185611662565b61171160408301846116d5565b949350505050565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f611783602a83611719565b915061178e82611729565b604082019050919050565b5f6020820190508181035f8301526117b081611777565b9050919050565b5f819050919050565b6117d16117cc82611367565b6117b7565b82525050565b5f6117e282846117c0565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f61181d826117f1565b61182781856117fb565b9350611837818560208601611805565b80840191505092915050565b5f61184e8284611813565b915081905092915050565b5f8151905061186781611370565b92915050565b5f6020828403121561188257611881611363565b5b5f61188f84828501611859565b91505092915050565b5f819050919050565b6118b26118ad8261139a565b611898565b82525050565b5f8160601b9050919050565b5f6118ce826118b8565b9050919050565b5f6118df826118c4565b9050919050565b6118f76118f2826113ec565b6118d5565b82525050565b5f61190882896118a1565b60208201915061191882886118e6565b60148201915061192882876118e6565b60148201915061193882866117c0565b60208201915061194882856117c0565b60208201915061195882846118e6565b601482019150819050979650505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f6119a0601383611719565b91506119ab8261196c565b602082019050919050565b5f6020820190508181035f8301526119cd81611994565b9050919050565b6119dd81611367565b82525050565b5f6020820190506119f65f8301846119d4565b92915050565b7f4d616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f611a56602483611719565b9150611a61826119fc565b604082019050919050565b5f6020820190508181035f830152611a8381611a4a565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f611abe601e83611719565b9150611ac982611a8a565b602082019050919050565b5f6020820190508181035f830152611aeb81611ab2565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f611b4c602383611719565b9150611b5782611af2565b604082019050919050565b5f6020820190508181035f830152611b7981611b40565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f611bda603883611719565b9150611be582611b80565b604082019050919050565b5f6020820190508181035f830152611c0781611bce565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f611c42601783611719565b9150611c4d82611c0e565b602082019050919050565b5f6020820190508181035f830152611c6f81611c36565b9050919050565b611c7f816113ec565b82525050565b611c8e8161139a565b82525050565b5f604082019050611ca75f830185611c76565b611cb46020830184611c85565b9392505050565b5f606082019050611cce5f830186611c76565b611cdb6020830185611c76565b611ce86040830184611c85565b949350505050565b5f8115159050919050565b611d0481611cf0565b8114611d0e575f80fd5b50565b5f81519050611d1f81611cfb565b92915050565b5f60208284031215611d3a57611d39611363565b5b5f611d4784828501611d11565b91505092915050565b5f602082019050611d635f830184611c76565b9291505056fea2646970667358221220565f86096f083c176a08cc3c220c01bd63eb7268584f034f3380299de3dac57f64736f6c63430008190033"; +pub const MAKER_SWAP_V2_BYTES: &str = include_str!("../../../mm2_test_helpers/contract_bytes/maker_swap_v2_bytes"); /// https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapTakerV2.sol -pub const TAKER_SWAP_V2_BYTES: &str = "60a060405234801561000f575f80fd5b50604051612a1b380380612a1b83398181016040528101906100319190610137565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361009f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610096906101e2565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505050610200565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610106826100dd565b9050919050565b610116816100fc565b8114610120575f80fd5b50565b5f815190506101318161010d565b92915050565b5f6020828403121561014c5761014b6100d9565b5b5f61015984828501610123565b91505092915050565b5f82825260208201905092915050565b7f66656541646472657373206d757374206e6f74206265207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f6101cc602383610162565b91506101d782610172565b604082019050919050565b5f6020820190508181035f8301526101f9816101c0565b9050919050565b6080516127f56102265f395f818161116d0152818161120801526115c401526127f55ff3fe60806040526004361061007a575f3560e01c80639b4603f21161004d5780639b4603f214610135578063cc90c19914610151578063d6a71eb414610179578063e06cf966146101a15761007a565b8063146e5b241461007e5780633e6af5f2146100a657806346b95ac7146100ce57806365e266171461010d575b5f80fd5b348015610089575f80fd5b506100a4600480360381019061009f91906119ef565b6101cb565b005b3480156100b1575f80fd5b506100cc60048036038101906100c791906119ef565b6103ae565b005b3480156100d9575f80fd5b506100f460048036038101906100ef9190611a8c565b6106bc565b6040516101049493929190611b82565b60405180910390f35b348015610118575f80fd5b50610133600480360381019061012e91906119ef565b61071d565b005b61014f600480360381019061014a9190611bef565b610b79565b005b34801561015c575f80fd5b50610177600480360381019061017291906119ef565b610ead565b005b348015610184575f80fd5b5061019f600480360381019061019a9190611c8c565b61125a565b005b3480156101ac575f80fd5b506101b56115c2565b6040516101c29190611d5f565b60405180910390f35b600160048111156101df576101de611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff16600481111561021157610210611b0f565b5b14610251576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024890611df8565b60405180910390fd5b5f6003878787338888886040516020016102719796959493929190611e9b565b60405160208183030381529060405260405161028d9190611f6d565b602060405180830381855afa1580156102a8573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610332576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032990611fcd565b60405180910390fd5b60025f808a81526020019081526020015f205f01601c6101000a81548160ff0219169083600481111561036857610367611b0f565b5b02179055507f9c45e43e2ef051f70491ffd5221bf02ab37e1324128714ef9610df5f24fc9fb58860405161039c9190611ffa565b60405180910390a15050505050505050565b600160048111156103c2576103c1611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660048111156103f4576103f3611b0f565b5b14610434576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042b90611df8565b60405180910390fd5b5f60038787873360028960405160200161044e9190612013565b60405160208183030381529060405260405161046a9190611f6d565b602060405180830381855afa158015610485573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906104a89190612041565b88886040516020016104c09796959493929190611e9b565b6040516020818303038152906040526040516104dc9190611f6d565b602060405180830381855afa1580156104f7573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610581576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057890611fcd565b60405180910390fd5b60045f808a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156105b7576105b6611b0f565b5b02179055507f45169a52eef651b20a81474b50b8a5d83225225fcd097ef3cf7952d9ab304f2788856040516105ed92919061206c565b60405180910390a15f868861060291906120c0565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610680573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f1935050505015801561067a573d5f803e3d5ffd5b506106b1565b5f8390506106af33838373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900463ffffffff1690805f01601c9054906101000a900460ff16905084565b6001600481111561073157610730611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff16600481111561076357610762611b0f565b5b14806107b257506002600481111561077e5761077d611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660048111156107b0576107af611b0f565b5b145b6107f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e890612163565b60405180910390fd5b5f6003878787338888886040516020016108119796959493929190611e9b565b60405160208183030381529060405260405161082d9190611f6d565b602060405180830381855afa158015610848573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146108d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c990611fcd565b60405180910390fd5b600260048111156108e6576108e5611b0f565b5b5f808a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561091857610917611b0f565b5b03610989575f808981526020019081526020015f205f0160189054906101000a900463ffffffff1663ffffffff16421015610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097f906121f1565b60405180910390fd5b5b6001600481111561099d5761099c611b0f565b5b5f808a81526020019081526020015f205f01601c9054906101000a900460ff1660048111156109cf576109ce611b0f565b5b03610a40575f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610a3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a369061227f565b60405180910390fd5b5b60045f808a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610a7657610a75611b0f565b5b02179055507fbdd7a4be6d82798a500b59077706b12d3f45acf5504828919f92501307b2b95388604051610aaa9190611ffa565b60405180910390a15f8688610abf91906120c0565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b3d573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015610b37573d5f803e3d5ffd5b50610b6e565b5f839050610b6c33838373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b505050505050505050565b5f6004811115610b8c57610b8b611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff166004811115610bbe57610bbd611b0f565b5b14610bfe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf59061230d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610c6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c639061239b565b60405180910390fd5b5f3411610cae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca590612429565b60405180910390fd5b853411610cf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce7906124b7565b60405180910390fd5b5f60038734610cff91906124d5565b88883389895f604051602001610d1b9796959493929190611e9b565b604051602081830303815290604052604051610d379190611f6d565b602060405180830381855afa158015610d52573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115610daa57610da9611b0f565b5b8152505f808a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115610e6457610e63611b0f565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd93588604051610e9b9190611ffa565b60405180910390a15050505050505050565b60026004811115610ec157610ec0611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff166004811115610ef357610ef2611b0f565b5b14610f33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2a90612578565b60405180910390fd5b5f60038787338888600289604051602001610f4e9190612013565b604051602081830303815290604052604051610f6a9190611f6d565b602060405180830381855afa158015610f85573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610fa89190612041565b88604051602001610fbf9796959493929190611e9b565b604051602081830303815290604052604051610fdb9190611f6d565b602060405180830381855afa158015610ff6573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611080576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107790611fcd565b60405180910390fd5b60035f808a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156110b6576110b5611b0f565b5b02179055507f0d0da0df275f85bed3a5fe7ae79f3559341a3f9ccd8e010133438135bda00a8788846040516110ec92919061206c565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111d4573373ffffffffffffffffffffffffffffffffffffffff166108fc8890811502906040515f60405180830381858888f1935050505015801561116a573d5f803e3d5ffd5b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f193505050501580156111ce573d5f803e3d5ffd5b50611250565b5f82905061120333898373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b61124e7f0000000000000000000000000000000000000000000000000000000000000000888373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b5050505050505050565b5f600481111561126d5761126c611b0f565b5b5f808b81526020019081526020015f205f01601c9054906101000a900460ff16600481111561129f5761129e611b0f565b5b146112df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d690612606565b60405180910390fd5b5f8811611321576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113189061266e565b60405180910390fd5b5f8711611363576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135a906126d6565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c89061239b565b60405180910390fd5b5f60038989883389898d6040516020016113f19796959493929190611e9b565b60405160208183030381529060405260405161140d9190611f6d565b602060405180830381855afa158015611428573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff168152602001600160048111156114805761147f611b0f565b5b8152505f808c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff0219169083600481111561153a57611539611b0f565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358a6040516115719190611ffa565b60405180910390a15f8790506115b533308b8d61158e91906120c0565b8473ffffffffffffffffffffffffffffffffffffffff16611665909392919063ffffffff16565b5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b611660838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401611619929190612703565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506116e7565b505050565b6116e1848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161169a9392919061272a565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506116e7565b50505050565b5f611711828473ffffffffffffffffffffffffffffffffffffffff1661177c90919063ffffffff16565b90505f8151141580156117355750808060200190518101906117339190612794565b155b1561177757826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161176e9190611d5f565b60405180910390fd5b505050565b606061178983835f611791565b905092915050565b6060814710156117d857306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016117cf9190611d5f565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516118009190611f6d565b5f6040518083038185875af1925050503d805f811461183a576040519150601f19603f3d011682016040523d82523d5f602084013e61183f565b606091505b509150915061184f86838361185a565b925050509392505050565b60608261186f5761186a826118e7565b6118df565b5f825114801561189557505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156118d757836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016118ce9190611d5f565b60405180910390fd5b8190506118e0565b5b9392505050565b5f815111156118f95780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80fd5b5f819050919050565b6119418161192f565b811461194b575f80fd5b50565b5f8135905061195c81611938565b92915050565b5f819050919050565b61197481611962565b811461197e575f80fd5b50565b5f8135905061198f8161196b565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6119be82611995565b9050919050565b6119ce816119b4565b81146119d8575f80fd5b50565b5f813590506119e9816119c5565b92915050565b5f805f805f805f60e0888a031215611a0a57611a0961192b565b5b5f611a178a828b0161194e565b9750506020611a288a828b01611981565b9650506040611a398a828b01611981565b9550506060611a4a8a828b016119db565b9450506080611a5b8a828b0161194e565b93505060a0611a6c8a828b0161194e565b92505060c0611a7d8a828b016119db565b91505092959891949750929550565b5f60208284031215611aa157611aa061192b565b5b5f611aae8482850161194e565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b611aeb81611ab7565b82525050565b5f63ffffffff82169050919050565b611b0981611af1565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60058110611b4d57611b4c611b0f565b5b50565b5f819050611b5d82611b3c565b919050565b5f611b6c82611b50565b9050919050565b611b7c81611b62565b82525050565b5f608082019050611b955f830187611ae2565b611ba26020830186611b00565b611baf6040830185611b00565b611bbc6060830184611b73565b95945050505050565b611bce81611af1565b8114611bd8575f80fd5b50565b5f81359050611be981611bc5565b92915050565b5f805f805f805f60e0888a031215611c0a57611c0961192b565b5b5f611c178a828b0161194e565b9750506020611c288a828b01611981565b9650506040611c398a828b016119db565b9550506060611c4a8a828b0161194e565b9450506080611c5b8a828b0161194e565b93505060a0611c6c8a828b01611bdb565b92505060c0611c7d8a828b01611bdb565b91505092959891949750929550565b5f805f805f805f805f6101208a8c031215611caa57611ca961192b565b5b5f611cb78c828d0161194e565b9950506020611cc88c828d01611981565b9850506040611cd98c828d01611981565b9750506060611cea8c828d016119db565b9650506080611cfb8c828d016119db565b95505060a0611d0c8c828d0161194e565b94505060c0611d1d8c828d0161194e565b93505060e0611d2e8c828d01611bdb565b925050610100611d408c828d01611bdb565b9150509295985092959850929598565b611d59816119b4565b82525050565b5f602082019050611d725f830184611d50565b92915050565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f611de2602a83611d78565b9150611ded82611d88565b604082019050919050565b5f6020820190508181035f830152611e0f81611dd6565b9050919050565b5f819050919050565b611e30611e2b82611962565b611e16565b82525050565b5f8160601b9050919050565b5f611e4c82611e36565b9050919050565b5f611e5d82611e42565b9050919050565b611e75611e70826119b4565b611e53565b82525050565b5f819050919050565b611e95611e908261192f565b611e7b565b82525050565b5f611ea6828a611e1f565b602082019150611eb68289611e1f565b602082019150611ec68288611e64565b601482019150611ed68287611e64565b601482019150611ee68286611e84565b602082019150611ef68285611e84565b602082019150611f068284611e64565b60148201915081905098975050505050505050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f611f4782611f1b565b611f518185611f25565b9350611f61818560208601611f2f565b80840191505092915050565b5f611f788284611f3d565b915081905092915050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f611fb7601383611d78565b9150611fc282611f83565b602082019050919050565b5f6020820190508181035f830152611fe481611fab565b9050919050565b611ff48161192f565b82525050565b5f60208201905061200d5f830184611feb565b92915050565b5f61201e8284611e84565b60208201915081905092915050565b5f8151905061203b81611938565b92915050565b5f602082840312156120565761205561192b565b5b5f6120638482850161202d565b91505092915050565b5f60408201905061207f5f830185611feb565b61208c6020830184611feb565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6120ca82611962565b91506120d583611962565b92508282019050808211156120ed576120ec612093565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e74206f722054616b6572417070726f7665640000000000602082015250565b5f61214d603b83611d78565b9150612158826120f3565b604082019050919050565b5f6020820190508181035f83015261217a81612141565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f6121db603883611d78565b91506121e682612181565b604082019050919050565b5f6020820190508181035f830152612208816121cf565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e74207072652d617070726f7665206c6f636b2074696d65000000602082015250565b5f612269603d83611d78565b91506122748261220f565b604082019050919050565b5f6020820190508181035f8301526122968161225d565b9050919050565b7f54616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f6122f7602483611d78565b91506123028261229d565b604082019050919050565b5f6020820190508181035f830152612324816122eb565b9050919050565b7f5265636569766572206d757374206e6f74206265207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f612385602183611d78565b91506123908261232b565b604082019050919050565b5f6020820190508181035f8301526123b281612379565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f612413602383611d78565b915061241e826123b9565b604082019050919050565b5f6020820190508181035f83015261244081612407565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e20645f8201527f6578206665650000000000000000000000000000000000000000000000000000602082015250565b5f6124a1602683611d78565b91506124ac82612447565b604082019050919050565b5f6020820190508181035f8301526124ce81612495565b9050919050565b5f6124df82611962565b91506124ea83611962565b925082820390508181111561250257612501612093565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520545f8201527f616b6572417070726f7665640000000000000000000000000000000000000000602082015250565b5f612562602c83611d78565b915061256d82612508565b604082019050919050565b5f6020820190508181035f83015261258f81612556565b9050919050565b7f4552433230207632207061796d656e7420697320616c726561647920696e69745f8201527f69616c697a656400000000000000000000000000000000000000000000000000602082015250565b5f6125f0602783611d78565b91506125fb82612596565b604082019050919050565b5f6020820190508181035f83015261261d816125e4565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f612658601783611d78565b915061266382612624565b602082019050919050565b5f6020820190508181035f8301526126858161264c565b9050919050565b7f44657820666565206d757374206e6f74206265207a65726f00000000000000005f82015250565b5f6126c0601883611d78565b91506126cb8261268c565b602082019050919050565b5f6020820190508181035f8301526126ed816126b4565b9050919050565b6126fd81611962565b82525050565b5f6040820190506127165f830185611d50565b61272360208301846126f4565b9392505050565b5f60608201905061273d5f830186611d50565b61274a6020830185611d50565b61275760408301846126f4565b949350505050565b5f8115159050919050565b6127738161275f565b811461277d575f80fd5b50565b5f8151905061278e8161276a565b92915050565b5f602082840312156127a9576127a861192b565b5b5f6127b684828501612780565b9150509291505056fea2646970667358221220fd2a736cddd6ebbd2831b0e65fb5470ffebd789dc32c1d3782ce69362e16fae564736f6c63430008190033"; +pub const TAKER_SWAP_V2_BYTES: &str = include_str!("../../../mm2_test_helpers/contract_bytes/taker_swap_v2_bytes"); pub trait CoinDockerOps { fn rpc_client(&self) -> &UtxoRpcClientEnum; diff --git a/mm2src/mm2_test_helpers/contract_bytes/erc1155_test_token_bytes b/mm2src/mm2_test_helpers/contract_bytes/erc1155_test_token_bytes new file mode 100644 index 0000000000..d5610ec91b --- /dev/null +++ b/mm2src/mm2_test_helpers/contract_bytes/erc1155_test_token_bytes @@ -0,0 +1 @@ +608060405234801562000010575f80fd5b50604051620024eb380380620024eb8339818101604052810190620000369190620001ea565b8062000048816200005060201b60201c565b505062000554565b806002908162000061919062000470565b5050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c6826200007e565b810181811067ffffffffffffffff82111715620000e857620000e76200008e565b5b80604052505050565b5f620000fc62000065565b90506200010a8282620000bb565b919050565b5f67ffffffffffffffff8211156200012c576200012b6200008e565b5b62000137826200007e565b9050602081019050919050565b5f5b838110156200016357808201518184015260208101905062000146565b5f8484015250505050565b5f620001846200017e846200010f565b620000f1565b905082815260208101848484011115620001a357620001a26200007a565b5b620001b084828562000144565b509392505050565b5f82601f830112620001cf57620001ce62000076565b5b8151620001e18482602086016200016e565b91505092915050565b5f602082840312156200020257620002016200006e565b5b5f82015167ffffffffffffffff81111562000222576200022162000072565b5b6200023084828501620001b8565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200028857607f821691505b6020821081036200029e576200029d62000243565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002c5565b6200030e8683620002c5565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f62000358620003526200034c8462000326565b6200032f565b62000326565b9050919050565b5f819050919050565b620003738362000338565b6200038b62000382826200035f565b848454620002d1565b825550505050565b5f90565b620003a162000393565b620003ae81848462000368565b505050565b5b81811015620003d557620003c95f8262000397565b600181019050620003b4565b5050565b601f8211156200042457620003ee81620002a4565b620003f984620002b6565b8101602085101562000409578190505b620004216200041885620002b6565b830182620003b3565b50505b505050565b5f82821c905092915050565b5f620004465f198460080262000429565b1980831691505092915050565b5f62000460838362000435565b9150826002028217905092915050565b6200047b8262000239565b67ffffffffffffffff8111156200049757620004966200008e565b5b620004a3825462000270565b620004b0828285620003d9565b5f60209050601f831160018114620004e6575f8415620004d1578287015190505b620004dd858262000453565b8655506200054c565b601f198416620004f686620002a4565b5f5b828110156200051f57848901518255600182019150602085019450602081019050620004f8565b868310156200053f57848901516200053b601f89168262000435565b8355505b6001600288020188555050505b505050505050565b611f8980620005625f395ff3fe608060405234801561000f575f80fd5b5060043610610090575f3560e01c80634e1273f4116100645780634e1273f414610140578063731133e914610170578063a22cb4651461018c578063e985e9c5146101a8578063f242432a146101d857610090565b8062fdd58e1461009457806301ffc9a7146100c45780630e89341c146100f45780632eb2c2d614610124575b5f80fd5b6100ae60048036038101906100a991906113bd565b6101f4565b6040516100bb919061140a565b60405180910390f35b6100de60048036038101906100d99190611478565b610249565b6040516100eb91906114bd565b60405180910390f35b61010e600480360381019061010991906114d6565b61032a565b60405161011b919061158b565b60405180910390f35b61013e6004803603810190610139919061179b565b6103bc565b005b61015a60048036038101906101559190611926565b610463565b6040516101679190611a53565b60405180910390f35b61018a60048036038101906101859190611a73565b61056a565b005b6101a660048036038101906101a19190611b1d565b61057c565b005b6101c260048036038101906101bd9190611b5b565b610592565b6040516101cf91906114bd565b60405180910390f35b6101f260048036038101906101ed9190611b99565b610620565b005b5f805f8381526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f7fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061031357507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103235750610322826106c7565b5b9050919050565b60606002805461033990611c59565b80601f016020809104026020016040519081016040528092919081815260200182805461036590611c59565b80156103b05780601f10610387576101008083540402835291602001916103b0565b820191905f5260205f20905b81548152906001019060200180831161039357829003601f168201915b50505050509050919050565b5f6103c5610730565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561040a57506104088682610592565b155b1561044e5780866040517fe237d922000000000000000000000000000000000000000000000000000000008152600401610445929190611c98565b60405180910390fd5b61045b8686868686610737565b505050505050565b606081518351146104af57815183516040517f5b0599910000000000000000000000000000000000000000000000000000000081526004016104a6929190611cbf565b60405180910390fd5b5f835167ffffffffffffffff8111156104cb576104ca6115af565b5b6040519080825280602002602001820160405280156104f95781602001602082028036833780820191505090505b5090505f5b845181101561055f5761053561051d828761082b90919063ffffffff16565b610530838761083e90919063ffffffff16565b6101f4565b82828151811061054857610547611ce6565b5b6020026020010181815250508060010190506104fe565b508091505092915050565b61057684848484610851565b50505050565b61058e610587610730565b83836108e6565b5050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f610629610730565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561066e575061066c8682610592565b155b156106b25780866040517fe237d9220000000000000000000000000000000000000000000000000000000081526004016106a9929190611c98565b60405180910390fd5b6106bf8686868686610a4f565b505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036107a7575f6040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161079e9190611d13565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610817575f6040517f01a8351400000000000000000000000000000000000000000000000000000000815260040161080e9190611d13565b60405180910390fd5b6108248585858585610b55565b5050505050565b5f60208202602084010151905092915050565b5f60208202602084010151905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036108c1575f6040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016108b89190611d13565b60405180910390fd5b5f806108cd8585610c01565b915091506108de5f87848487610b55565b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610956575f6040517fced3e10000000000000000000000000000000000000000000000000000000000815260040161094d9190611d13565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610a4291906114bd565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610abf575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401610ab69190611d13565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610b2f575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401610b269190611d13565b60405180910390fd5b5f80610b3b8585610c01565b91509150610b4c8787848487610b55565b50505050505050565b610b6185858585610c31565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610bfa575f610b9d610730565b90506001845103610be9575f610bbc5f8661083e90919063ffffffff16565b90505f610bd25f8661083e90919063ffffffff16565b9050610be2838989858589610fc1565b5050610bf8565b610bf7818787878787611170565b5b505b5050505050565b60608060405191506001825283602083015260408201905060018152826020820152604081016040529250929050565b8051825114610c7b57815181516040517f5b059991000000000000000000000000000000000000000000000000000000008152600401610c72929190611cbf565b60405180910390fd5b5f610c84610730565b90505f5b8351811015610e80575f610ca5828661083e90919063ffffffff16565b90505f610cbb838661083e90919063ffffffff16565b90505f73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614610dde575f805f8481526020019081526020015f205f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015610d8a57888183856040517f03dee4c5000000000000000000000000000000000000000000000000000000008152600401610d819493929190611d2c565b60405180910390fd5b8181035f808581526020019081526020015f205f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610e7357805f808481526020019081526020015f205f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610e6b9190611d9c565b925050819055505b5050806001019050610c88565b506001835103610f3b575f610e9e5f8561083e90919063ffffffff16565b90505f610eb45f8561083e90919063ffffffff16565b90508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051610f2c929190611cbf565b60405180910390a45050610fba565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051610fb1929190611dcf565b60405180910390a45b5050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115611168578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b8152600401611021959493929190611e56565b6020604051808303815f875af192505050801561105c57506040513d601f19601f820116820180604052508101906110599190611ec2565b60015b6110dd573d805f811461108a576040519150601f19603f3d011682016040523d82523d5f602084013e61108f565b606091505b505f8151036110d557846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016110cc9190611d13565b60405180910390fd5b805181602001fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461116657846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161115d9190611d13565b60405180910390fd5b505b505050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115611317578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b81526004016111d0959493929190611eed565b6020604051808303815f875af192505050801561120b57506040513d601f19601f820116820180604052508101906112089190611ec2565b60015b61128c573d805f8114611239576040519150601f19603f3d011682016040523d82523d5f602084013e61123e565b606091505b505f81510361128457846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161127b9190611d13565b60405180910390fd5b805181602001fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461131557846040517f57f447ce00000000000000000000000000000000000000000000000000000000815260040161130c9190611d13565b60405180910390fd5b505b505050505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61135982611330565b9050919050565b6113698161134f565b8114611373575f80fd5b50565b5f8135905061138481611360565b92915050565b5f819050919050565b61139c8161138a565b81146113a6575f80fd5b50565b5f813590506113b781611393565b92915050565b5f80604083850312156113d3576113d2611328565b5b5f6113e085828601611376565b92505060206113f1858286016113a9565b9150509250929050565b6114048161138a565b82525050565b5f60208201905061141d5f8301846113fb565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61145781611423565b8114611461575f80fd5b50565b5f813590506114728161144e565b92915050565b5f6020828403121561148d5761148c611328565b5b5f61149a84828501611464565b91505092915050565b5f8115159050919050565b6114b7816114a3565b82525050565b5f6020820190506114d05f8301846114ae565b92915050565b5f602082840312156114eb576114ea611328565b5b5f6114f8848285016113a9565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561153857808201518184015260208101905061151d565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61155d82611501565b611567818561150b565b935061157781856020860161151b565b61158081611543565b840191505092915050565b5f6020820190508181035f8301526115a38184611553565b905092915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6115e582611543565b810181811067ffffffffffffffff82111715611604576116036115af565b5b80604052505050565b5f61161661131f565b905061162282826115dc565b919050565b5f67ffffffffffffffff821115611641576116406115af565b5b602082029050602081019050919050565b5f80fd5b5f61166861166384611627565b61160d565b9050808382526020820190506020840283018581111561168b5761168a611652565b5b835b818110156116b457806116a088826113a9565b84526020840193505060208101905061168d565b5050509392505050565b5f82601f8301126116d2576116d16115ab565b5b81356116e2848260208601611656565b91505092915050565b5f80fd5b5f67ffffffffffffffff821115611709576117086115af565b5b61171282611543565b9050602081019050919050565b828183375f83830152505050565b5f61173f61173a846116ef565b61160d565b90508281526020810184848401111561175b5761175a6116eb565b5b61176684828561171f565b509392505050565b5f82601f830112611782576117816115ab565b5b813561179284826020860161172d565b91505092915050565b5f805f805f60a086880312156117b4576117b3611328565b5b5f6117c188828901611376565b95505060206117d288828901611376565b945050604086013567ffffffffffffffff8111156117f3576117f261132c565b5b6117ff888289016116be565b935050606086013567ffffffffffffffff8111156118205761181f61132c565b5b61182c888289016116be565b925050608086013567ffffffffffffffff81111561184d5761184c61132c565b5b6118598882890161176e565b9150509295509295909350565b5f67ffffffffffffffff8211156118805761187f6115af565b5b602082029050602081019050919050565b5f6118a361189e84611866565b61160d565b905080838252602082019050602084028301858111156118c6576118c5611652565b5b835b818110156118ef57806118db8882611376565b8452602084019350506020810190506118c8565b5050509392505050565b5f82601f83011261190d5761190c6115ab565b5b813561191d848260208601611891565b91505092915050565b5f806040838503121561193c5761193b611328565b5b5f83013567ffffffffffffffff8111156119595761195861132c565b5b611965858286016118f9565b925050602083013567ffffffffffffffff8111156119865761198561132c565b5b611992858286016116be565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6119ce8161138a565b82525050565b5f6119df83836119c5565b60208301905092915050565b5f602082019050919050565b5f611a018261199c565b611a0b81856119a6565b9350611a16836119b6565b805f5b83811015611a46578151611a2d88826119d4565b9750611a38836119eb565b925050600181019050611a19565b5085935050505092915050565b5f6020820190508181035f830152611a6b81846119f7565b905092915050565b5f805f8060808587031215611a8b57611a8a611328565b5b5f611a9887828801611376565b9450506020611aa9878288016113a9565b9350506040611aba878288016113a9565b925050606085013567ffffffffffffffff811115611adb57611ada61132c565b5b611ae78782880161176e565b91505092959194509250565b611afc816114a3565b8114611b06575f80fd5b50565b5f81359050611b1781611af3565b92915050565b5f8060408385031215611b3357611b32611328565b5b5f611b4085828601611376565b9250506020611b5185828601611b09565b9150509250929050565b5f8060408385031215611b7157611b70611328565b5b5f611b7e85828601611376565b9250506020611b8f85828601611376565b9150509250929050565b5f805f805f60a08688031215611bb257611bb1611328565b5b5f611bbf88828901611376565b9550506020611bd088828901611376565b9450506040611be1888289016113a9565b9350506060611bf2888289016113a9565b925050608086013567ffffffffffffffff811115611c1357611c1261132c565b5b611c1f8882890161176e565b9150509295509295909350565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611c7057607f821691505b602082108103611c8357611c82611c2c565b5b50919050565b611c928161134f565b82525050565b5f604082019050611cab5f830185611c89565b611cb86020830184611c89565b9392505050565b5f604082019050611cd25f8301856113fb565b611cdf60208301846113fb565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f602082019050611d265f830184611c89565b92915050565b5f608082019050611d3f5f830187611c89565b611d4c60208301866113fb565b611d5960408301856113fb565b611d6660608301846113fb565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611da68261138a565b9150611db18361138a565b9250828201905080821115611dc957611dc8611d6f565b5b92915050565b5f6040820190508181035f830152611de781856119f7565b90508181036020830152611dfb81846119f7565b90509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f611e2882611e04565b611e328185611e0e565b9350611e4281856020860161151b565b611e4b81611543565b840191505092915050565b5f60a082019050611e695f830188611c89565b611e766020830187611c89565b611e8360408301866113fb565b611e9060608301856113fb565b8181036080830152611ea28184611e1e565b90509695505050505050565b5f81519050611ebc8161144e565b92915050565b5f60208284031215611ed757611ed6611328565b5b5f611ee484828501611eae565b91505092915050565b5f60a082019050611f005f830188611c89565b611f0d6020830187611c89565b8181036040830152611f1f81866119f7565b90508181036060830152611f3381856119f7565b90508181036080830152611f478184611e1e565b9050969550505050505056fea26469706673582212203835581c6344b12728c44fa4d9e912cd60e64012c1b772bb703d1c36825c16fd64736f6c63430008180033 \ No newline at end of file diff --git a/mm2src/mm2_test_helpers/contract_bytes/erc20_token_bytes b/mm2src/mm2_test_helpers/contract_bytes/erc20_token_bytes new file mode 100644 index 0000000000..21d608c62d --- /dev/null +++ b/mm2src/mm2_test_helpers/contract_bytes/erc20_token_bytes @@ -0,0 +1 @@ +6080604052600860ff16600a0a633b9aca000260005534801561002157600080fd5b50600054600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610c69806100776000396000f3006080604052600436106100a4576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100a9578063095ea7b31461013957806318160ddd1461019e57806323b872dd146101c9578063313ce5671461024e5780635a3b7e421461027f57806370a082311461030f57806395d89b4114610366578063a9059cbb146103f6578063dd62ed3e1461045b575b600080fd5b3480156100b557600080fd5b506100be6104d2565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100fe5780820151818401526020810190506100e3565b50505050905090810190601f16801561012b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014557600080fd5b50610184600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061050b565b604051808215151515815260200191505060405180910390f35b3480156101aa57600080fd5b506101b36106bb565b6040518082815260200191505060405180910390f35b3480156101d557600080fd5b50610234600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506106c1565b604051808215151515815260200191505060405180910390f35b34801561025a57600080fd5b506102636109a1565b604051808260ff1660ff16815260200191505060405180910390f35b34801561028b57600080fd5b506102946109a6565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102d45780820151818401526020810190506102b9565b50505050905090810190601f1680156103015780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561031b57600080fd5b50610350600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109df565b6040518082815260200191505060405180910390f35b34801561037257600080fd5b5061037b6109f7565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103bb5780820151818401526020810190506103a0565b50505050905090810190601f1680156103e85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561040257600080fd5b50610441600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a30565b604051808215151515815260200191505060405180910390f35b34801561046757600080fd5b506104bc600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610be1565b6040518082815260200191505060405180910390f35b6040805190810160405280600881526020017f515243205445535400000000000000000000000000000000000000000000000081525081565b60008260008173ffffffffffffffffffffffffffffffffffffffff161415151561053457600080fd5b60008314806105bf57506000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054145b15156105ca57600080fd5b82600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925856040518082815260200191505060405180910390a3600191505092915050565b60005481565b60008360008173ffffffffffffffffffffffffffffffffffffffff16141515156106ea57600080fd5b8360008173ffffffffffffffffffffffffffffffffffffffff161415151561071157600080fd5b610797600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485610c06565b600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610860600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485610c06565b600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506108ec600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485610c1f565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef866040518082815260200191505060405180910390a36001925050509392505050565b600881565b6040805190810160405280600981526020017f546f6b656e20302e31000000000000000000000000000000000000000000000081525081565b60016020528060005260406000206000915090505481565b6040805190810160405280600381526020017f515443000000000000000000000000000000000000000000000000000000000081525081565b60008260008173ffffffffffffffffffffffffffffffffffffffff1614151515610a5957600080fd5b610aa2600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205484610c06565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610b2e600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205484610c1f565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191505092915050565b6002602052816000526040600020602052806000526040600020600091509150505481565b6000818310151515610c1457fe5b818303905092915050565b6000808284019050838110151515610c3357fe5b80915050929150505600a165627a7a723058207f2e5248b61b80365ea08a0f6d11ac0b47374c4dfd538de76bc2f19591bbbba40029 \ No newline at end of file diff --git a/mm2src/mm2_test_helpers/contract_bytes/erc721_test_token_bytes b/mm2src/mm2_test_helpers/contract_bytes/erc721_test_token_bytes new file mode 100644 index 0000000000..62f7b588b2 --- /dev/null +++ b/mm2src/mm2_test_helpers/contract_bytes/erc721_test_token_bytes @@ -0,0 +1 @@ +608060405234801562000010575f80fd5b50604051620022ac380380620022ac8339818101604052810190620000369190620001ea565b8181815f9081620000489190620004a4565b5080600190816200005a9190620004a4565b505050505062000588565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c6826200007e565b810181811067ffffffffffffffff82111715620000e857620000e76200008e565b5b80604052505050565b5f620000fc62000065565b90506200010a8282620000bb565b919050565b5f67ffffffffffffffff8211156200012c576200012b6200008e565b5b62000137826200007e565b9050602081019050919050565b5f5b838110156200016357808201518184015260208101905062000146565b5f8484015250505050565b5f620001846200017e846200010f565b620000f1565b905082815260208101848484011115620001a357620001a26200007a565b5b620001b084828562000144565b509392505050565b5f82601f830112620001cf57620001ce62000076565b5b8151620001e18482602086016200016e565b91505092915050565b5f80604083850312156200020357620002026200006e565b5b5f83015167ffffffffffffffff81111562000223576200022262000072565b5b6200023185828601620001b8565b925050602083015167ffffffffffffffff81111562000255576200025462000072565b5b6200026385828601620001b8565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620002bc57607f821691505b602082108103620002d257620002d162000277565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002f9565b620003428683620002f9565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200038c6200038662000380846200035a565b62000363565b6200035a565b9050919050565b5f819050919050565b620003a7836200036c565b620003bf620003b68262000393565b84845462000305565b825550505050565b5f90565b620003d5620003c7565b620003e28184846200039c565b505050565b5b818110156200040957620003fd5f82620003cb565b600181019050620003e8565b5050565b601f82111562000458576200042281620002d8565b6200042d84620002ea565b810160208510156200043d578190505b620004556200044c85620002ea565b830182620003e7565b50505b505050565b5f82821c905092915050565b5f6200047a5f19846008026200045d565b1980831691505092915050565b5f62000494838362000469565b9150826002028217905092915050565b620004af826200026d565b67ffffffffffffffff811115620004cb57620004ca6200008e565b5b620004d78254620002a4565b620004e48282856200040d565b5f60209050601f8311600181146200051a575f841562000505578287015190505b62000511858262000487565b86555062000580565b601f1984166200052a86620002d8565b5f5b8281101562000553578489015182556001820191506020850194506020810190506200052c565b868310156200057357848901516200056f601f89168262000469565b8355505b6001600288020188555050505b505050505050565b611d1680620005965f395ff3fe608060405234801561000f575f80fd5b50600436106100e8575f3560e01c80636352211e1161008a578063a22cb46511610064578063a22cb46514610258578063b88d4fde14610274578063c87b56dd14610290578063e985e9c5146102c0576100e8565b80636352211e146101da57806370a082311461020a57806395d89b411461023a576100e8565b8063095ea7b3116100c6578063095ea7b31461016a57806323b872dd1461018657806340c10f19146101a257806342842e0e146101be576100e8565b806301ffc9a7146100ec57806306fdde031461011c578063081812fc1461013a575b5f80fd5b610106600480360381019061010191906115a7565b6102f0565b60405161011391906115ec565b60405180910390f35b6101246103d1565b604051610131919061168f565b60405180910390f35b610154600480360381019061014f91906116e2565b610460565b604051610161919061174c565b60405180910390f35b610184600480360381019061017f919061178f565b61047b565b005b6101a0600480360381019061019b91906117cd565b610491565b005b6101bc60048036038101906101b7919061178f565b610590565b005b6101d860048036038101906101d391906117cd565b61059e565b005b6101f460048036038101906101ef91906116e2565b6105bd565b604051610201919061174c565b60405180910390f35b610224600480360381019061021f919061181d565b6105ce565b6040516102319190611857565b60405180910390f35b610242610684565b60405161024f919061168f565b60405180910390f35b610272600480360381019061026d919061189a565b610714565b005b61028e60048036038101906102899190611a04565b61072a565b005b6102aa60048036038101906102a591906116e2565b610747565b6040516102b7919061168f565b60405180910390f35b6102da60048036038101906102d59190611a84565b6107ad565b6040516102e791906115ec565b60405180910390f35b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103ba57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103ca57506103c98261083b565b5b9050919050565b60605f80546103df90611aef565b80601f016020809104026020016040519081016040528092919081815260200182805461040b90611aef565b80156104565780601f1061042d57610100808354040283529160200191610456565b820191905f5260205f20905b81548152906001019060200180831161043957829003601f168201915b5050505050905090565b5f61046a826108a4565b506104748261092a565b9050919050565b61048d8282610488610963565b61096a565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610501575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016104f8919061174c565b60405180910390fd5b5f610514838361050f610963565b61097c565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461058a578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161058193929190611b1f565b60405180910390fd5b50505050565b61059a8282610b87565b5050565b6105b883838360405180602001604052805f81525061072a565b505050565b5f6105c7826108a4565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361063f575f6040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401610636919061174c565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b60606001805461069390611aef565b80601f01602080910402602001604051908101604052809291908181526020018280546106bf90611aef565b801561070a5780601f106106e15761010080835404028352916020019161070a565b820191905f5260205f20905b8154815290600101906020018083116106ed57829003601f168201915b5050505050905090565b61072661071f610963565b8383610c7a565b5050565b610735848484610491565b61074184848484610de3565b50505050565b6060610752826108a4565b505f61075c610f95565b90505f81511161077a5760405180602001604052805f8152506107a5565b8061078484610fab565b604051602001610795929190611b8e565b6040516020818303038152906040525b915050919050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f806108af83611075565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361092157826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016109189190611857565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b61097783838360016110ae565b505050565b5f8061098784611075565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146109c8576109c781848661126d565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a5357610a075f855f806110ae565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610ad257600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610bf7575f6040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610bee919061174c565b60405180910390fd5b5f610c0383835f61097c565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c75575f6040517f73c6ac6e000000000000000000000000000000000000000000000000000000008152600401610c6c919061174c565b60405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610cea57816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401610ce1919061174c565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610dd691906115ec565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b1115610f8f578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02610e26610963565b8685856040518563ffffffff1660e01b8152600401610e489493929190611c03565b6020604051808303815f875af1925050508015610e8357506040513d601f19601f82011682018060405250810190610e809190611c61565b60015b610f04573d805f8114610eb1576040519150601f19603f3d011682016040523d82523d5f602084013e610eb6565b606091505b505f815103610efc57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610ef3919061174c565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614610f8d57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610f84919061174c565b60405180910390fd5b505b50505050565b606060405180602001604052805f815250905090565b60605f6001610fb984611330565b0190505f8167ffffffffffffffff811115610fd757610fd66118e0565b5b6040519080825280601f01601f1916602001820160405280156110095781602001600182028036833780820191505090505b5090505f82602001820190505b60011561106a578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161105f5761105e611c8c565b5b0494505f8503611016575b819350505050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b80806110e657505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611218575f6110f5846108a4565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561115f57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611172575061117081846107ad565b155b156111b457826040517fa9fbf51f0000000000000000000000000000000000000000000000000000000081526004016111ab919061174c565b60405180910390fd5b811561121657838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b611278838383611481565b61132b575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036112ec57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016112e39190611857565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401611322929190611cb9565b60405180910390fd5b505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061138c577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161138257611381611c8c565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106113c9576d04ee2d6d415b85acef810000000083816113bf576113be611c8c565b5b0492506020810190505b662386f26fc1000083106113f857662386f26fc1000083816113ee576113ed611c8c565b5b0492506010810190505b6305f5e1008310611421576305f5e100838161141757611416611c8c565b5b0492506008810190505b612710831061144657612710838161143c5761143b611c8c565b5b0492506004810190505b60648310611469576064838161145f5761145e611c8c565b5b0492506002810190505b600a8310611478576001810190505b80915050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561153857508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806114f957506114f884846107ad565b5b8061153757508273ffffffffffffffffffffffffffffffffffffffff1661151f8361092a565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61158681611552565b8114611590575f80fd5b50565b5f813590506115a18161157d565b92915050565b5f602082840312156115bc576115bb61154a565b5b5f6115c984828501611593565b91505092915050565b5f8115159050919050565b6115e6816115d2565b82525050565b5f6020820190506115ff5f8301846115dd565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561163c578082015181840152602081019050611621565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61166182611605565b61166b818561160f565b935061167b81856020860161161f565b61168481611647565b840191505092915050565b5f6020820190508181035f8301526116a78184611657565b905092915050565b5f819050919050565b6116c1816116af565b81146116cb575f80fd5b50565b5f813590506116dc816116b8565b92915050565b5f602082840312156116f7576116f661154a565b5b5f611704848285016116ce565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6117368261170d565b9050919050565b6117468161172c565b82525050565b5f60208201905061175f5f83018461173d565b92915050565b61176e8161172c565b8114611778575f80fd5b50565b5f8135905061178981611765565b92915050565b5f80604083850312156117a5576117a461154a565b5b5f6117b28582860161177b565b92505060206117c3858286016116ce565b9150509250929050565b5f805f606084860312156117e4576117e361154a565b5b5f6117f18682870161177b565b93505060206118028682870161177b565b9250506040611813868287016116ce565b9150509250925092565b5f602082840312156118325761183161154a565b5b5f61183f8482850161177b565b91505092915050565b611851816116af565b82525050565b5f60208201905061186a5f830184611848565b92915050565b611879816115d2565b8114611883575f80fd5b50565b5f8135905061189481611870565b92915050565b5f80604083850312156118b0576118af61154a565b5b5f6118bd8582860161177b565b92505060206118ce85828601611886565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61191682611647565b810181811067ffffffffffffffff82111715611935576119346118e0565b5b80604052505050565b5f611947611541565b9050611953828261190d565b919050565b5f67ffffffffffffffff821115611972576119716118e0565b5b61197b82611647565b9050602081019050919050565b828183375f83830152505050565b5f6119a86119a384611958565b61193e565b9050828152602081018484840111156119c4576119c36118dc565b5b6119cf848285611988565b509392505050565b5f82601f8301126119eb576119ea6118d8565b5b81356119fb848260208601611996565b91505092915050565b5f805f8060808587031215611a1c57611a1b61154a565b5b5f611a298782880161177b565b9450506020611a3a8782880161177b565b9350506040611a4b878288016116ce565b925050606085013567ffffffffffffffff811115611a6c57611a6b61154e565b5b611a78878288016119d7565b91505092959194509250565b5f8060408385031215611a9a57611a9961154a565b5b5f611aa78582860161177b565b9250506020611ab88582860161177b565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611b0657607f821691505b602082108103611b1957611b18611ac2565b5b50919050565b5f606082019050611b325f83018661173d565b611b3f6020830185611848565b611b4c604083018461173d565b949350505050565b5f81905092915050565b5f611b6882611605565b611b728185611b54565b9350611b8281856020860161161f565b80840191505092915050565b5f611b998285611b5e565b9150611ba58284611b5e565b91508190509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f611bd582611bb1565b611bdf8185611bbb565b9350611bef81856020860161161f565b611bf881611647565b840191505092915050565b5f608082019050611c165f83018761173d565b611c23602083018661173d565b611c306040830185611848565b8181036060830152611c428184611bcb565b905095945050505050565b5f81519050611c5b8161157d565b92915050565b5f60208284031215611c7657611c7561154a565b5b5f611c8384828501611c4d565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f604082019050611ccc5f83018561173d565b611cd96020830184611848565b939250505056fea26469706673582212207439b47c2a9a1624955997732075917bbf1da26949d000c778f561eb5687576164736f6c63430008180033 \ No newline at end of file diff --git a/mm2src/mm2_test_helpers/contract_bytes/maker_swap_v2_bytes b/mm2src/mm2_test_helpers/contract_bytes/maker_swap_v2_bytes new file mode 100644 index 0000000000..5b8bda7350 --- /dev/null +++ b/mm2src/mm2_test_helpers/contract_bytes/maker_swap_v2_bytes @@ -0,0 +1 @@ +6080604052348015600e575f80fd5b50611d9f8061001c5f395ff3fe608060405260043610610054575f3560e01c80631299a27a146100585780637466be601461008057806374a4788a1461009c5780639b949dee146100c4578063a53bc126146100ec578063efccb9eb14610114575b5f80fd5b348015610063575f80fd5b5061007e60048036038101906100799190611427565b610152565b005b61009a600480360381019061009591906114e9565b61044b565b005b3480156100a7575f80fd5b506100c260048036038101906100bd9190611427565b6106fc565b005b3480156100cf575f80fd5b506100ea60048036038101906100e59190611427565b6109f5565b005b3480156100f7575f80fd5b50610112600480360381019061010d9190611560565b610ced565b005b34801561011f575f80fd5b5061013a600480360381019061013591906115fd565b610fd2565b604051610149939291906116e4565b60405180910390f35b6001600381111561016657610165611671565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561019857610197611671565b5b146101d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101cf90611799565b60405180910390fd5b5f6003863387876002886040516020016101f291906117d7565b60405160208183030381529060405260405161020e9190611843565b602060405180830381855afa158015610229573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061024c919061186d565b87604051602001610262969594939291906118fd565b60405160208183030381529060405260405161027e9190611843565b602060405180830381855afa158015610299573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610323576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031a906119b6565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561035957610358611671565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161038d91906119e3565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610411573373ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f1935050505015801561040b573d5f803e3d5ffd5b50610442565b5f82905061044033888373ffffffffffffffffffffffffffffffffffffffff1661101e9092919063ffffffff16565b505b50505050505050565b5f600381111561045e5761045d611671565b5b5f808781526020019081526020015f205f0160189054906101000a900460ff1660038111156104905761048f611671565b5b146104d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c790611a6c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361053e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053590611ad4565b60405180910390fd5b5f3411610580576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057790611b62565b60405180910390fd5b5f600334863387875f60405160200161059e969594939291906118fd565b6040516020818303038152906040526040516105ba9190611843565b602060405180830381855afa1580156105d5573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018363ffffffff1681526020016001600381111561062157610620611671565b5b8152505f808881526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156106b5576106b4611671565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad866040516106ec91906119e3565b60405180910390a1505050505050565b600160038111156107105761070f611671565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561074257610741611671565b5b14610782576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161077990611799565b60405180910390fd5b5f600386863360028860405160200161079b91906117d7565b6040516020818303038152906040526040516107b79190611843565b602060405180830381855afa1580156107d2573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107f5919061186d565b878760405160200161080c969594939291906118fd565b6040516020818303038152906040526040516108289190611843565b602060405180830381855afa158015610843573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146108cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c4906119b6565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561090357610902611671565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd738760405161093791906119e3565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036109bb573373ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f193505050501580156109b5573d5f803e3d5ffd5b506109ec565b5f8290506109ea33888373ffffffffffffffffffffffffffffffffffffffff1661101e9092919063ffffffff16565b505b50505050505050565b60016003811115610a0957610a08611671565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff166003811115610a3b57610a3a611671565b5b14610a7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7290611799565b60405180910390fd5b5f6003868633878787604051602001610a99969594939291906118fd565b604051602081830303815290604052604051610ab59190611843565b602060405180830381855afa158015610ad0573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610b5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b51906119b6565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610bc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbc90611bf0565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610bfb57610bfa611671565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907287604051610c2f91906119e3565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610cb3573373ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f19350505050158015610cad573d5f803e3d5ffd5b50610ce4565b5f829050610ce233888373ffffffffffffffffffffffffffffffffffffffff1661101e9092919063ffffffff16565b505b50505050505050565b5f6003811115610d0057610cff611671565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115610d3257610d31611671565b5b14610d72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6990611a6c565b60405180910390fd5b5f8611610db4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dab90611c58565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610e22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1990611ad4565b60405180910390fd5b5f600387863387878b604051602001610e40969594939291906118fd565b604051602081830303815290604052604051610e5c9190611843565b602060405180830381855afa158015610e77573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018363ffffffff16815260200160016003811115610ec357610ec2611671565b5b8152505f808a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115610f5757610f56611671565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad88604051610f8e91906119e3565b60405180910390a15f869050610fc733308a8473ffffffffffffffffffffffffffffffffffffffff1661109d909392919063ffffffff16565b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b611098838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401611051929190611c94565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061111f565b505050565b611119848573ffffffffffffffffffffffffffffffffffffffff166323b872dd8686866040516024016110d293929190611cbb565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061111f565b50505050565b5f611149828473ffffffffffffffffffffffffffffffffffffffff166111b490919063ffffffff16565b90505f81511415801561116d57508080602001905181019061116b9190611d25565b155b156111af57826040517f5274afe70000000000000000000000000000000000000000000000000000000081526004016111a69190611d50565b60405180910390fd5b505050565b60606111c183835f6111c9565b905092915050565b60608147101561121057306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016112079190611d50565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516112389190611843565b5f6040518083038185875af1925050503d805f8114611272576040519150601f19603f3d011682016040523d82523d5f602084013e611277565b606091505b5091509150611287868383611292565b925050509392505050565b6060826112a7576112a28261131f565b611317565b5f82511480156112cd57505f8473ffffffffffffffffffffffffffffffffffffffff163b145b1561130f57836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016113069190611d50565b60405180910390fd5b819050611318565b5b9392505050565b5f815111156113315780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80fd5b5f819050919050565b61137981611367565b8114611383575f80fd5b50565b5f8135905061139481611370565b92915050565b5f819050919050565b6113ac8161139a565b81146113b6575f80fd5b50565b5f813590506113c7816113a3565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6113f6826113cd565b9050919050565b611406816113ec565b8114611410575f80fd5b50565b5f81359050611421816113fd565b92915050565b5f805f805f8060c0878903121561144157611440611363565b5b5f61144e89828a01611386565b965050602061145f89828a016113b9565b955050604061147089828a01611413565b945050606061148189828a01611386565b935050608061149289828a01611386565b92505060a06114a389828a01611413565b9150509295509295509295565b5f63ffffffff82169050919050565b6114c8816114b0565b81146114d2575f80fd5b50565b5f813590506114e3816114bf565b92915050565b5f805f805f60a0868803121561150257611501611363565b5b5f61150f88828901611386565b955050602061152088828901611413565b945050604061153188828901611386565b935050606061154288828901611386565b9250506080611553888289016114d5565b9150509295509295909350565b5f805f805f805f60e0888a03121561157b5761157a611363565b5b5f6115888a828b01611386565b97505060206115998a828b016113b9565b96505060406115aa8a828b01611413565b95505060606115bb8a828b01611413565b94505060806115cc8a828b01611386565b93505060a06115dd8a828b01611386565b92505060c06115ee8a828b016114d5565b91505092959891949750929550565b5f6020828403121561161257611611611363565b5b5f61161f84828501611386565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b61165c81611628565b82525050565b61166b816114b0565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600481106116af576116ae611671565b5b50565b5f8190506116bf8261169e565b919050565b5f6116ce826116b2565b9050919050565b6116de816116c4565b82525050565b5f6060820190506116f75f830186611653565b6117046020830185611662565b61171160408301846116d5565b949350505050565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f611783602a83611719565b915061178e82611729565b604082019050919050565b5f6020820190508181035f8301526117b081611777565b9050919050565b5f819050919050565b6117d16117cc82611367565b6117b7565b82525050565b5f6117e282846117c0565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f61181d826117f1565b61182781856117fb565b9350611837818560208601611805565b80840191505092915050565b5f61184e8284611813565b915081905092915050565b5f8151905061186781611370565b92915050565b5f6020828403121561188257611881611363565b5b5f61188f84828501611859565b91505092915050565b5f819050919050565b6118b26118ad8261139a565b611898565b82525050565b5f8160601b9050919050565b5f6118ce826118b8565b9050919050565b5f6118df826118c4565b9050919050565b6118f76118f2826113ec565b6118d5565b82525050565b5f61190882896118a1565b60208201915061191882886118e6565b60148201915061192882876118e6565b60148201915061193882866117c0565b60208201915061194882856117c0565b60208201915061195882846118e6565b601482019150819050979650505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f6119a0601383611719565b91506119ab8261196c565b602082019050919050565b5f6020820190508181035f8301526119cd81611994565b9050919050565b6119dd81611367565b82525050565b5f6020820190506119f65f8301846119d4565b92915050565b7f4d616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f611a56602483611719565b9150611a61826119fc565b604082019050919050565b5f6020820190508181035f830152611a8381611a4a565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f611abe601e83611719565b9150611ac982611a8a565b602082019050919050565b5f6020820190508181035f830152611aeb81611ab2565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f611b4c602383611719565b9150611b5782611af2565b604082019050919050565b5f6020820190508181035f830152611b7981611b40565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f611bda603883611719565b9150611be582611b80565b604082019050919050565b5f6020820190508181035f830152611c0781611bce565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f611c42601783611719565b9150611c4d82611c0e565b602082019050919050565b5f6020820190508181035f830152611c6f81611c36565b9050919050565b611c7f816113ec565b82525050565b611c8e8161139a565b82525050565b5f604082019050611ca75f830185611c76565b611cb46020830184611c85565b9392505050565b5f606082019050611cce5f830186611c76565b611cdb6020830185611c76565b611ce86040830184611c85565b949350505050565b5f8115159050919050565b611d0481611cf0565b8114611d0e575f80fd5b50565b5f81519050611d1f81611cfb565b92915050565b5f60208284031215611d3a57611d39611363565b5b5f611d4784828501611d11565b91505092915050565b5f602082019050611d635f830184611c76565b9291505056fea2646970667358221220565f86096f083c176a08cc3c220c01bd63eb7268584f034f3380299de3dac57f64736f6c63430008190033 \ No newline at end of file diff --git a/mm2src/mm2_test_helpers/contract_bytes/nft_maker_swap_v2_bytes b/mm2src/mm2_test_helpers/contract_bytes/nft_maker_swap_v2_bytes new file mode 100644 index 0000000000..93922e9594 --- /dev/null +++ b/mm2src/mm2_test_helpers/contract_bytes/nft_maker_swap_v2_bytes @@ -0,0 +1 @@ +6080604052348015600e575f80fd5b506131fa8061001c5f395ff3fe608060405234801561000f575f80fd5b50600436106100cd575f3560e01c8063bc197c811161008a578063eb4ab61211610064578063eb4ab61214610209578063efccb9eb14610225578063f0e9fcd114610257578063f23a6e6114610273576100cd565b8063bc197c81146101a1578063c8d9009b146101d1578063c92cd12d146101ed576100cd565b806301ffc9a7146100d157806305ec158d146101015780630f235fce1461011d578063150b7a02146101395780636e6bf6d214610169578063b27e46fb14610185575b5f80fd5b6100eb60048036038101906100e69190612005565b6102a3565b6040516100f8919061204a565b60405180910390f35b61011b60048036038101906101169190612123565b610384565b005b610137600480360381019061013291906121c0565b610644565b005b610153600480360381019061014e91906122aa565b6108fe565b604051610160919061233d565b60405180910390f35b610183600480360381019061017e91906121c0565b610d4d565b005b61019f600480360381019061019a9190612123565b611008565b005b6101bb60048036038101906101b691906123ab565b6112c7565b6040516101c8919061233d565b60405180910390f35b6101eb60048036038101906101e691906121c0565b611303565b005b61020760048036038101906102029190612123565b61162c565b005b610223600480360381019061021e9190612482565b61195a565b005b61023f600480360381019061023a91906124e6565b6119d1565b60405161024e939291906125dc565b60405180910390f35b610271600480360381019061026c9190612611565b611a1d565b005b61028d60048036038101906102889190612661565b611a91565b60405161029a919061233d565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061036d57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061037d575061037c82611f25565b5b9050919050565b6001600381111561039857610397612569565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff1660038111156103ca576103c9612569565b5b1461040a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161040190612777565b60405180910390fd5b5f6003873360028960405160200161042291906127b5565b60405160208183030381529060405260405161043e9190612821565b602060405180830381855afa158015610459573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061047c919061284b565b8888888860405160200161049697969594939291906128db565b6040516020818303038152906040526040516104b29190612821565b602060405180830381855afa1580156104cd573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610557576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161054e906129a5565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561058d5761058c612569565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd73886040516105c191906129d2565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161060c9493929190612a3c565b5f604051808303815f87803b158015610623575f80fd5b505af1158015610635573d5f803e3d5ffd5b50505050505050505050505050565b6001600381111561065857610657612569565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561068a57610689612569565b5b146106ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c190612777565b60405180910390fd5b5f60038633878787876040516020016106e896959493929190612a92565b6040516020818303038152906040526040516107049190612821565b602060405180830381855afa15801561071f573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146107a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107a0906129a5565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610814576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161080b90612b71565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561084a57610849612569565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad192190728760405161087e91906129d2565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016108c793929190612b8f565b5f604051808303815f87803b1580156108de575f80fd5b505af11580156108f0573d5f803e3d5ffd5b505050505050505050505050565b5f80838381019061090f9190612d17565b90505f600381111561092457610923612569565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff16600381111561095957610958612569565b5b14610999576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099090612db2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603610a0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0290612e1a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610a7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7490612e82565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610aef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae690612f10565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610b5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5490612f78565b60405180910390fd5b610b6a8160200151611f8e565b15610baa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba190612fe0565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610bd896959493929190612a92565b604051602081830303815290604052604051610bf49190612821565b602060405180830381855afa158015610c0f573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115610c5f57610c5e612569565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115610cf657610cf5612569565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051610d3091906129d2565b60405180910390a163150b7a0260e01b9250505095945050505050565b60016003811115610d6157610d60612569565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff166003811115610d9357610d92612569565b5b14610dd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dca90612777565b60405180910390fd5b5f60038633600288604051602001610deb91906127b5565b604051602081830303815290604052604051610e079190612821565b602060405180830381855afa158015610e22573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610e45919061284b565b878787604051602001610e5d96959493929190612a92565b604051602081830303815290604052604051610e799190612821565b602060405180830381855afa158015610e94573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610f1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f15906129a5565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610f5457610f53612569565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051610f8891906129d2565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610fd193929190612b8f565b5f604051808303815f87803b158015610fe8575f80fd5b505af1158015610ffa573d5f803e3d5ffd5b505050505050505050505050565b6001600381111561101c5761101b612569565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561104e5761104d612569565b5b1461108e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108590612777565b60405180910390fd5b5f6003873388888888886040516020016110ae97969594939291906128db565b6040516020818303038152906040526040516110ca9190612821565b602060405180830381855afa1580156110e5573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461116f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611166906129a5565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156111da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d190612b71565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156112105761120f612569565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad192190728860405161124491906129d2565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161128f9493929190612a3c565b5f604051808303815f87803b1580156112a6575f80fd5b505af11580156112b8573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112fa90613048565b60405180910390fd5b6001600381111561131757611316612569565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561134957611348612569565b5b14611389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138090612777565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ee906130b0565b60405180910390fd5b5f600333878760028860405160200161141091906127b5565b60405160208183030381529060405260405161142c9190612821565b602060405180830381855afa158015611447573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061146a919061284b565b878760405160200161148196959493929190612a92565b60405160208183030381529060405260405161149d9190612821565b602060405180830381855afa1580156114b8573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611542576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611539906129a5565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561157857611577612569565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0876040516115ac91906129d2565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016115f593929190612b8f565b5f604051808303815f87803b15801561160c575f80fd5b505af115801561161e573d5f803e3d5ffd5b505050505050505050505050565b600160038111156116405761163f612569565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561167257611671612569565b5b146116b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a990612777565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611720576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611717906130b0565b60405180910390fd5b5f600333888860028960405160200161173991906127b5565b6040516020818303038152906040526040516117559190612821565b602060405180830381855afa158015611770573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190611793919061284b565b8888886040516020016117ac97969594939291906128db565b6040516020818303038152906040526040516117c89190612821565b602060405180830381855afa1580156117e3573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461186d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611864906129a5565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156118a3576118a2612569565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0886040516118d791906129d2565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016119229493929190612a3c565b5f604051808303815f87803b158015611939575f80fd5b505af115801561194b573d5f803e3d5ffd5b50505050505050505050505050565b5f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a308487876040518563ffffffff1660e01b815260040161199d9493929190612a3c565b5f604051808303815f87803b1580156119b4575f80fd5b505af11580156119c6573d5f803e3d5ffd5b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3084866040518463ffffffff1660e01b8152600401611a5e93929190612b8f565b5f604051808303815f87803b158015611a75575f80fd5b505af1158015611a87573d5f803e3d5ffd5b5050505050505050565b5f808383810190611aa29190612d17565b90505f6003811115611ab757611ab6612569565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff166003811115611aec57611aeb612569565b5b14611b2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b239061313e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603611b9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9590612e1a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603611c10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c0790612e82565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7990612f10565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614611cf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce790612f78565b60405180910390fd5b5f8511611d32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d29906131a6565b60405180910390fd5b611d3f8160200151611f8e565b15611d7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7690612fe0565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c604051602001611daf97969594939291906128db565b604051602081830303815290604052604051611dcb9190612821565b602060405180830381855afa158015611de6573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115611e3657611e35612569565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115611ecd57611ecc612569565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051611f0791906129d2565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611fe481611fb0565b8114611fee575f80fd5b50565b5f81359050611fff81611fdb565b92915050565b5f6020828403121561201a57612019611fa8565b5b5f61202784828501611ff1565b91505092915050565b5f8115159050919050565b61204481612030565b82525050565b5f60208201905061205d5f83018461203b565b92915050565b5f819050919050565b61207581612063565b811461207f575f80fd5b50565b5f813590506120908161206c565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6120bf82612096565b9050919050565b6120cf816120b5565b81146120d9575f80fd5b50565b5f813590506120ea816120c6565b92915050565b5f819050919050565b612102816120f0565b811461210c575f80fd5b50565b5f8135905061211d816120f9565b92915050565b5f805f805f805f60e0888a03121561213e5761213d611fa8565b5b5f61214b8a828b01612082565b975050602061215c8a828b016120dc565b965050604061216d8a828b01612082565b955050606061217e8a828b01612082565b945050608061218f8a828b016120dc565b93505060a06121a08a828b0161210f565b92505060c06121b18a828b0161210f565b91505092959891949750929550565b5f805f805f8060c087890312156121da576121d9611fa8565b5b5f6121e789828a01612082565b96505060206121f889828a016120dc565b955050604061220989828a01612082565b945050606061221a89828a01612082565b935050608061222b89828a016120dc565b92505060a061223c89828a0161210f565b9150509295509295509295565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261226a57612269612249565b5b8235905067ffffffffffffffff8111156122875761228661224d565b5b6020830191508360018202830111156122a3576122a2612251565b5b9250929050565b5f805f805f608086880312156122c3576122c2611fa8565b5b5f6122d0888289016120dc565b95505060206122e1888289016120dc565b94505060406122f28882890161210f565b935050606086013567ffffffffffffffff81111561231357612312611fac565b5b61231f88828901612255565b92509250509295509295909350565b61233781611fb0565b82525050565b5f6020820190506123505f83018461232e565b92915050565b5f8083601f84011261236b5761236a612249565b5b8235905067ffffffffffffffff8111156123885761238761224d565b5b6020830191508360208202830111156123a4576123a3612251565b5b9250929050565b5f805f805f805f8060a0898b0312156123c7576123c6611fa8565b5b5f6123d48b828c016120dc565b98505060206123e58b828c016120dc565b975050604089013567ffffffffffffffff81111561240657612405611fac565b5b6124128b828c01612356565b9650965050606089013567ffffffffffffffff81111561243557612434611fac565b5b6124418b828c01612356565b9450945050608089013567ffffffffffffffff81111561246457612463611fac565b5b6124708b828c01612255565b92509250509295985092959890939650565b5f805f806080858703121561249a57612499611fa8565b5b5f6124a7878288016120dc565b94505060206124b88782880161210f565b93505060406124c98782880161210f565b92505060606124da878288016120dc565b91505092959194509250565b5f602082840312156124fb576124fa611fa8565b5b5f61250884828501612082565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b61254581612511565b82525050565b5f63ffffffff82169050919050565b6125638161254b565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600481106125a7576125a6612569565b5b50565b5f8190506125b782612596565b919050565b5f6125c6826125aa565b9050919050565b6125d6816125bc565b82525050565b5f6060820190506125ef5f83018661253c565b6125fc602083018561255a565b61260960408301846125cd565b949350505050565b5f805f6060848603121561262857612627611fa8565b5b5f612635868287016120dc565b93505060206126468682870161210f565b9250506040612657868287016120dc565b9150509250925092565b5f805f805f8060a0878903121561267b5761267a611fa8565b5b5f61268889828a016120dc565b965050602061269989828a016120dc565b95505060406126aa89828a0161210f565b94505060606126bb89828a0161210f565b935050608087013567ffffffffffffffff8111156126dc576126db611fac565b5b6126e889828a01612255565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f612761602a836126f7565b915061276c82612707565b604082019050919050565b5f6020820190508181035f83015261278e81612755565b9050919050565b5f819050919050565b6127af6127aa82612063565b612795565b82525050565b5f6127c0828461279e565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6127fb826127cf565b61280581856127d9565b93506128158185602086016127e3565b80840191505092915050565b5f61282c82846127f1565b915081905092915050565b5f815190506128458161206c565b92915050565b5f602082840312156128605761285f611fa8565b5b5f61286d84828501612837565b91505092915050565b5f8160601b9050919050565b5f61288c82612876565b9050919050565b5f61289d82612882565b9050919050565b6128b56128b0826120b5565b612893565b82525050565b5f819050919050565b6128d56128d0826120f0565b6128bb565b82525050565b5f6128e6828a6128a4565b6014820191506128f682896128a4565b601482019150612906828861279e565b602082019150612916828761279e565b60208201915061292682866128a4565b60148201915061293682856128c4565b60208201915061294682846128c4565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f61298f6013836126f7565b915061299a8261295b565b602082019050919050565b5f6020820190508181035f8301526129bc81612983565b9050919050565b6129cc81612063565b82525050565b5f6020820190506129e55f8301846129c3565b92915050565b6129f4816120b5565b82525050565b612a03816120f0565b82525050565b5f82825260208201905092915050565b50565b5f612a275f83612a09565b9150612a3282612a19565b5f82019050919050565b5f60a082019050612a4f5f8301876129eb565b612a5c60208301866129eb565b612a6960408301856129fa565b612a7660608301846129fa565b8181036080830152612a8781612a1c565b905095945050505050565b5f612a9d82896128a4565b601482019150612aad82886128a4565b601482019150612abd828761279e565b602082019150612acd828661279e565b602082019150612add82856128a4565b601482019150612aed82846128c4565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f612b5b6038836126f7565b9150612b6682612b01565b604082019050919050565b5f6020820190508181035f830152612b8881612b4f565b9050919050565b5f606082019050612ba25f8301866129eb565b612baf60208301856129eb565b612bbc60408301846129fa565b949350505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612c0e82612bc8565b810181811067ffffffffffffffff82111715612c2d57612c2c612bd8565b5b80604052505050565b5f612c3f611f9f565b9050612c4b8282612c05565b919050565b612c598161254b565b8114612c63575f80fd5b50565b5f81359050612c7481612c50565b92915050565b5f60c08284031215612c8f57612c8e612bc4565b5b612c9960c0612c36565b90505f612ca884828501612082565b5f830152506020612cbb848285016120dc565b6020830152506040612ccf848285016120dc565b6040830152506060612ce384828501612082565b6060830152506080612cf784828501612082565b60808301525060a0612d0b84828501612c66565b60a08301525092915050565b5f60c08284031215612d2c57612d2b611fa8565b5b5f612d3984828501612c7a565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f612d9c602a836126f7565b9150612da782612d42565b604082019050919050565b5f6020820190508181035f830152612dc981612d90565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612e04601e836126f7565b9150612e0f82612dd0565b602082019050919050565b5f6020820190508181035f830152612e3181612df8565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612e6c601e836126f7565b9150612e7782612e38565b602082019050919050565b5f6020820190508181035f830152612e9981612e60565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f612efa6023836126f7565b9150612f0582612ea0565b604082019050919050565b5f6020820190508181035f830152612f2781612eee565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f612f62601b836126f7565b9150612f6d82612f2e565b602082019050919050565b5f6020820190508181035f830152612f8f81612f56565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f612fca601a836126f7565b9150612fd582612f96565b602082019050919050565b5f6020820190508181035f830152612ff781612fbe565b9050919050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f613032601d836126f7565b915061303d82612ffe565b602082019050919050565b5f6020820190508181035f83015261305f81613026565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f61309a6015836126f7565b91506130a582613066565b602082019050919050565b5f6020820190508181035f8301526130c78161308e565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f613128602b836126f7565b9150613133826130ce565b604082019050919050565b5f6020820190508181035f8301526131558161311c565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f613190601c836126f7565b915061319b8261315c565b602082019050919050565b5f6020820190508181035f8301526131bd81613184565b905091905056fea2646970667358221220c7235610f4c08b95d1e01bd31ff0b8b671c0f18c33212760a2ce3b09e6ad77e964736f6c63430008190033 \ No newline at end of file diff --git a/mm2src/mm2_test_helpers/contract_bytes/nft_swap_contract_bytes b/mm2src/mm2_test_helpers/contract_bytes/nft_swap_contract_bytes new file mode 100644 index 0000000000..44c1930271 --- /dev/null +++ b/mm2src/mm2_test_helpers/contract_bytes/nft_swap_contract_bytes @@ -0,0 +1 @@ +60a060405234801562000010575f80fd5b50604051620055a2380380620055a2833981810160405281019062000036919062000147565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200009e90620001fb565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506200021b565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200011182620000e6565b9050919050565b620001238162000105565b81146200012e575f80fd5b50565b5f81519050620001418162000118565b92915050565b5f602082840312156200015f576200015e620000e2565b5b5f6200016e8482850162000131565b91505092915050565b5f82825260208201905092915050565b7f66656541646472657373206d757374206e6f74206265207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f620001e360238362000177565b9150620001f08262000187565b604082019050919050565b5f6020820190508181035f8301526200021481620001d5565b9050919050565b608051615360620002425f395f8181612aef01528181612b8a0152612f4801526153605ff3fe608060405260043610610113575f3560e01c80639b4603f21161009f578063cc90c19911610063578063cc90c1991461038e578063d6a71eb4146103b6578063e06cf966146103de578063efccb9eb14610408578063f23a6e611461044657610113565b80639b4603f2146102be578063b27e46fb146102da578063bc197c8114610302578063c8d9009b1461033e578063c92cd12d1461036657610113565b8063150b7a02116100e6578063150b7a02146101cb5780633e6af5f21461020757806346b95ac71461022f57806365e266171461026e5780636e6bf6d21461029657610113565b806301ffc9a71461011757806305ec158d146101535780630f235fce1461017b578063146e5b24146101a3575b5f80fd5b348015610122575f80fd5b5061013d6004803603810190610138919061386f565b610482565b60405161014a91906138b4565b60405180910390f35b34801561015e575f80fd5b506101796004803603810190610174919061398d565b610563565b005b348015610186575f80fd5b506101a1600480360381019061019c9190613a2a565b610823565b005b3480156101ae575f80fd5b506101c960048036038101906101c49190613ab3565b610add565b005b3480156101d6575f80fd5b506101f160048036038101906101ec9190613bb1565b610cc3565b6040516101fe9190613c44565b60405180910390f35b348015610212575f80fd5b5061022d60048036038101906102289190613ab3565b611112565b005b34801561023a575f80fd5b5061025560048036038101906102509190613c5d565b611423565b6040516102659493929190613d53565b60405180910390f35b348015610279575f80fd5b50610294600480360381019061028f9190613ab3565b611485565b005b3480156102a1575f80fd5b506102bc60048036038101906102b79190613a2a565b6118e9565b005b6102d860048036038101906102d39190613dc0565b611ba4565b005b3480156102e5575f80fd5b5061030060048036038101906102fb919061398d565b611eda565b005b34801561030d575f80fd5b5061032860048036038101906103239190613eb2565b612199565b6040516103359190613c44565b60405180910390f35b348015610349575f80fd5b50610364600480360381019061035f9190613a2a565b6121d5565b005b348015610371575f80fd5b5061038c6004803603810190610387919061398d565b6124fe565b005b348015610399575f80fd5b506103b460048036038101906103af9190613ab3565b61282c565b005b3480156103c1575f80fd5b506103dc60048036038101906103d79190613f89565b612bdc565b005b3480156103e9575f80fd5b506103f2612f46565b6040516103ff919061405c565b60405180910390f35b348015610413575f80fd5b5061042e60048036038101906104299190613c5d565b612f6a565b60405161043d939291906140bb565b60405180910390f35b348015610451575f80fd5b5061046c600480360381019061046791906140f0565b612fb6565b6040516104799190613c44565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061054c57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061055c575061055b8261344a565b5b9050919050565b6001600381111561057757610576613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff1660038111156105a9576105a8613ce0565b5b146105e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e090614206565b60405180910390fd5b5f600387336002896040516020016106019190614244565b60405160208183030381529060405260405161061d91906142ca565b602060405180830381855afa158015610638573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065b91906142f4565b888888886040516020016106759796959493929190614384565b60405160208183030381529060405260405161069191906142ca565b602060405180830381855afa1580156106ac573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610736576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072d9061444e565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561076c5761076b613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd73886040516107a0919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016107eb94939291906144d6565b5f604051808303815f87803b158015610802575f80fd5b505af1158015610814573d5f803e3d5ffd5b50505050505050505050505050565b6001600381111561083757610836613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561086957610868613ce0565b5b146108a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a090614206565b60405180910390fd5b5f60038633878787876040516020016108c79695949392919061452c565b6040516020818303038152906040526040516108e391906142ca565b602060405180830381855afa1580156108fe573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097f9061444e565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156109f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ea9061460b565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610a2957610a28613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907287604051610a5d919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610aa693929190614629565b5f604051808303815f87803b158015610abd575f80fd5b505af1158015610acf573d5f803e3d5ffd5b505050505050505050505050565b60016004811115610af157610af0613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115610b2457610b23613ce0565b5b14610b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5b90614206565b60405180910390fd5b5f600387878733888888604051602001610b84979695949392919061465e565b604051602081830303815290604052604051610ba091906142ca565b602060405180830381855afa158015610bbb573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610c46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3d9061444e565b60405180910390fd5b600260015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610c7d57610c7c613ce0565b5b02179055507f9c45e43e2ef051f70491ffd5221bf02ab37e1324128714ef9610df5f24fc9fb588604051610cb1919061447b565b60405180910390a15050505050505050565b5f808383810190610cd49190614807565b90505f6003811115610ce957610ce8613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff166003811115610d1e57610d1d613ce0565b5b14610d5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d55906148a2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603610dd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc79061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610e42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3990614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610eb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eab90614a00565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610f22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1990614a68565b60405180910390fd5b610f2f81602001516134b3565b15610f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6690614ad0565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610f9d9695949392919061452c565b604051602081830303815290604052604051610fb991906142ca565b602060405180830381855afa158015610fd4573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561102457611023613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156110bb576110ba613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f01516040516110f5919061447b565b60405180910390a163150b7a0260e01b9250505095945050505050565b6001600481111561112657611125613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561115957611158613ce0565b5b14611199576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119090614206565b60405180910390fd5b5f6003878787336002896040516020016111b39190614244565b6040516020818303038152906040526040516111cf91906142ca565b602060405180830381855afa1580156111ea573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061120d91906142f4565b8888604051602001611225979695949392919061465e565b60405160208183030381529060405260405161124191906142ca565b602060405180830381855afa15801561125c573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146112e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112de9061444e565b60405180910390fd5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff0219169083600481111561131e5761131d613ce0565b5b02179055507f45169a52eef651b20a81474b50b8a5d83225225fcd097ef3cf7952d9ab304f278885604051611354929190614aee565b60405180910390a15f86886113699190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113e7573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156113e1573d5f803e3d5ffd5b50611418565b5f83905061141633838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b6001602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900463ffffffff1690805f01601c9054906101000a900460ff16905084565b6001600481111561149957611498613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff1660048111156114cc576114cb613ce0565b5b148061151c5750600260048111156114e7576114e6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561151a57611519613ce0565b5b145b61155b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155290614be5565b60405180910390fd5b5f60038787873388888860405160200161157b979695949392919061465e565b60405160208183030381529060405260405161159791906142ca565b602060405180830381855afa1580156115b2573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461163d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116349061444e565b60405180910390fd5b6002600481111561165157611650613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561168457611683613ce0565b5b036116f65760015f8981526020019081526020015f205f0160189054906101000a900463ffffffff1663ffffffff164210156116f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ec9061460b565b60405180910390fd5b5b6001600481111561170a57611709613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561173d5761173c613ce0565b5b036117af5760015f8981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156117ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a590614c73565b60405180910390fd5b5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156117e6576117e5613ce0565b5b02179055507fbdd7a4be6d82798a500b59077706b12d3f45acf5504828919f92501307b2b9538860405161181a919061447b565b60405180910390a15f868861182f9190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118ad573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156118a7573d5f803e3d5ffd5b506118de565b5f8390506118dc33838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b600160038111156118fd576118fc613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561192f5761192e613ce0565b5b1461196f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196690614206565b60405180910390fd5b5f600386336002886040516020016119879190614244565b6040516020818303038152906040526040516119a391906142ca565b602060405180830381855afa1580156119be573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906119e191906142f4565b8787876040516020016119f99695949392919061452c565b604051602081830303815290604052604051611a1591906142ca565b602060405180830381855afa158015611a30573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611aba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab19061444e565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115611af057611aef613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051611b24919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401611b6d93929190614629565b5f604051808303815f87803b158015611b84575f80fd5b505af1158015611b96573d5f803e3d5ffd5b505050505050505050505050565b5f6004811115611bb757611bb6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115611bea57611be9613ce0565b5b14611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2190614d01565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611c98576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8f90614d8f565b60405180910390fd5b5f3411611cda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd190614e1d565b60405180910390fd5b853411611d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1390614eab565b60405180910390fd5b5f60038734611d2b9190614ec9565b88883389895f604051602001611d47979695949392919061465e565b604051602081830303815290604052604051611d6391906142ca565b602060405180830381855afa158015611d7e573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115611dd657611dd5613ce0565b5b81525060015f8a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115611e9157611e90613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd93588604051611ec8919061447b565b60405180910390a15050505050505050565b60016003811115611eee57611eed613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115611f2057611f1f613ce0565b5b14611f60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5790614206565b60405180910390fd5b5f600387338888888888604051602001611f809796959493929190614384565b604051602081830303815290604052604051611f9c91906142ca565b602060405180830381855afa158015611fb7573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612041576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120389061444e565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156120ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a39061460b565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156120e2576120e1613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907288604051612116919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161216194939291906144d6565b5f604051808303815f87803b158015612178575f80fd5b505af115801561218a573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121cc90614f46565b60405180910390fd5b600160038111156121e9576121e8613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561221b5761221a613ce0565b5b1461225b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161225290614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c090614fae565b60405180910390fd5b5f60033387876002886040516020016122e29190614244565b6040516020818303038152906040526040516122fe91906142ca565b602060405180830381855afa158015612319573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061233c91906142f4565b87876040516020016123539695949392919061452c565b60405160208183030381529060405260405161236f91906142ca565b602060405180830381855afa15801561238a573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612414576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240b9061444e565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561244a57612449613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161247e919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016124c793929190614629565b5f604051808303815f87803b1580156124de575f80fd5b505af11580156124f0573d5f803e3d5ffd5b505050505050505050505050565b6001600381111561251257612511613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561254457612543613ce0565b5b14612584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257b90614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146125f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125e990614fae565b60405180910390fd5b5f600333888860028960405160200161260b9190614244565b60405160208183030381529060405260405161262791906142ca565b602060405180830381855afa158015612642573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061266591906142f4565b88888860405160200161267e9796959493929190614384565b60405160208183030381529060405260405161269a91906142ca565b602060405180830381855afa1580156126b5573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461273f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127369061444e565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561277557612774613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0886040516127a9919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016127f494939291906144d6565b5f604051808303815f87803b15801561280b575f80fd5b505af115801561281d573d5f803e3d5ffd5b50505050505050505050505050565b600260048111156128405761283f613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561287357612872613ce0565b5b146128b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128aa9061503c565b60405180910390fd5b5f600387873388886002896040516020016128ce9190614244565b6040516020818303038152906040526040516128ea91906142ca565b602060405180830381855afa158015612905573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061292891906142f4565b8860405160200161293f979695949392919061465e565b60405160208183030381529060405260405161295b91906142ca565b602060405180830381855afa158015612976573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612a01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129f89061444e565b60405180910390fd5b600360015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115612a3857612a37613ce0565b5b02179055507f0d0da0df275f85bed3a5fe7ae79f3559341a3f9ccd8e010133438135bda00a878884604051612a6e929190614aee565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612b56573373ffffffffffffffffffffffffffffffffffffffff166108fc8890811502906040515f60405180830381858888f19350505050158015612aec573d5f803e3d5ffd5b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f19350505050158015612b50573d5f803e3d5ffd5b50612bd2565b5f829050612b8533898373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b612bd07f0000000000000000000000000000000000000000000000000000000000000000888373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b5050505050505050565b5f6004811115612bef57612bee613ce0565b5b60015f8b81526020019081526020015f205f01601c9054906101000a900460ff166004811115612c2257612c21613ce0565b5b14612c62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c59906150ca565b60405180910390fd5b5f8811612ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c9b90615132565b60405180910390fd5b5f8711612ce6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cdd9061519a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612d54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d4b90614d8f565b60405180910390fd5b5f60038989883389898d604051602001612d74979695949392919061465e565b604051602081830303815290604052604051612d9091906142ca565b602060405180830381855afa158015612dab573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115612e0357612e02613ce0565b5b81525060015f8c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115612ebe57612ebd613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358a604051612ef5919061447b565b60405180910390a15f879050612f3933308b8d612f129190614b42565b8473ffffffffffffffffffffffffffffffffffffffff16613543909392919063ffffffff16565b5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f808383810190612fc79190614807565b90505f6003811115612fdc57612fdb613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff16600381111561301157613010613ce0565b5b14613051576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161304890615228565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff16036130c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130ba9061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161312c90614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146131a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161319e90614a00565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614613215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161320c90614a68565b60405180910390fd5b5f8511613257576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161324e90615290565b60405180910390fd5b61326481602001516134b3565b156132a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161329b90614ad0565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c6040516020016132d49796959493929190614384565b6040516020818303038152906040526040516132f091906142ca565b602060405180830381855afa15801561330b573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561335b5761335a613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156133f2576133f1613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f015160405161342c919061447b565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b61353e838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85856040516024016134f79291906152ae565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b505050565b6135bf848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161357893929190614629565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b50505050565b5f6135ef828473ffffffffffffffffffffffffffffffffffffffff1661365a90919063ffffffff16565b90505f81511415801561361357508080602001905181019061361191906152ff565b155b1561365557826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161364c919061405c565b60405180910390fd5b505050565b606061366783835f61366f565b905092915050565b6060814710156136b657306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016136ad919061405c565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516136de91906142ca565b5f6040518083038185875af1925050503d805f8114613718576040519150601f19603f3d011682016040523d82523d5f602084013e61371d565b606091505b509150915061372d868383613738565b925050509392505050565b60608261374d57613748826137c5565b6137bd565b5f825114801561377357505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156137b557836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016137ac919061405c565b60405180910390fd5b8190506137be565b5b9392505050565b5f815111156137d75780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61384e8161381a565b8114613858575f80fd5b50565b5f8135905061386981613845565b92915050565b5f6020828403121561388457613883613812565b5b5f6138918482850161385b565b91505092915050565b5f8115159050919050565b6138ae8161389a565b82525050565b5f6020820190506138c75f8301846138a5565b92915050565b5f819050919050565b6138df816138cd565b81146138e9575f80fd5b50565b5f813590506138fa816138d6565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61392982613900565b9050919050565b6139398161391f565b8114613943575f80fd5b50565b5f8135905061395481613930565b92915050565b5f819050919050565b61396c8161395a565b8114613976575f80fd5b50565b5f8135905061398781613963565b92915050565b5f805f805f805f60e0888a0312156139a8576139a7613812565b5b5f6139b58a828b016138ec565b97505060206139c68a828b01613946565b96505060406139d78a828b016138ec565b95505060606139e88a828b016138ec565b94505060806139f98a828b01613946565b93505060a0613a0a8a828b01613979565b92505060c0613a1b8a828b01613979565b91505092959891949750929550565b5f805f805f8060c08789031215613a4457613a43613812565b5b5f613a5189828a016138ec565b9650506020613a6289828a01613946565b9550506040613a7389828a016138ec565b9450506060613a8489828a016138ec565b9350506080613a9589828a01613946565b92505060a0613aa689828a01613979565b9150509295509295509295565b5f805f805f805f60e0888a031215613ace57613acd613812565b5b5f613adb8a828b016138ec565b9750506020613aec8a828b01613979565b9650506040613afd8a828b01613979565b9550506060613b0e8a828b01613946565b9450506080613b1f8a828b016138ec565b93505060a0613b308a828b016138ec565b92505060c0613b418a828b01613946565b91505092959891949750929550565b5f80fd5b5f80fd5b5f80fd5b5f8083601f840112613b7157613b70613b50565b5b8235905067ffffffffffffffff811115613b8e57613b8d613b54565b5b602083019150836001820283011115613baa57613ba9613b58565b5b9250929050565b5f805f805f60808688031215613bca57613bc9613812565b5b5f613bd788828901613946565b9550506020613be888828901613946565b9450506040613bf988828901613979565b935050606086013567ffffffffffffffff811115613c1a57613c19613816565b5b613c2688828901613b5c565b92509250509295509295909350565b613c3e8161381a565b82525050565b5f602082019050613c575f830184613c35565b92915050565b5f60208284031215613c7257613c71613812565b5b5f613c7f848285016138ec565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b613cbc81613c88565b82525050565b5f63ffffffff82169050919050565b613cda81613cc2565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60058110613d1e57613d1d613ce0565b5b50565b5f819050613d2e82613d0d565b919050565b5f613d3d82613d21565b9050919050565b613d4d81613d33565b82525050565b5f608082019050613d665f830187613cb3565b613d736020830186613cd1565b613d806040830185613cd1565b613d8d6060830184613d44565b95945050505050565b613d9f81613cc2565b8114613da9575f80fd5b50565b5f81359050613dba81613d96565b92915050565b5f805f805f805f60e0888a031215613ddb57613dda613812565b5b5f613de88a828b016138ec565b9750506020613df98a828b01613979565b9650506040613e0a8a828b01613946565b9550506060613e1b8a828b016138ec565b9450506080613e2c8a828b016138ec565b93505060a0613e3d8a828b01613dac565b92505060c0613e4e8a828b01613dac565b91505092959891949750929550565b5f8083601f840112613e7257613e71613b50565b5b8235905067ffffffffffffffff811115613e8f57613e8e613b54565b5b602083019150836020820283011115613eab57613eaa613b58565b5b9250929050565b5f805f805f805f8060a0898b031215613ece57613ecd613812565b5b5f613edb8b828c01613946565b9850506020613eec8b828c01613946565b975050604089013567ffffffffffffffff811115613f0d57613f0c613816565b5b613f198b828c01613e5d565b9650965050606089013567ffffffffffffffff811115613f3c57613f3b613816565b5b613f488b828c01613e5d565b9450945050608089013567ffffffffffffffff811115613f6b57613f6a613816565b5b613f778b828c01613b5c565b92509250509295985092959890939650565b5f805f805f805f805f6101208a8c031215613fa757613fa6613812565b5b5f613fb48c828d016138ec565b9950506020613fc58c828d01613979565b9850506040613fd68c828d01613979565b9750506060613fe78c828d01613946565b9650506080613ff88c828d01613946565b95505060a06140098c828d016138ec565b94505060c061401a8c828d016138ec565b93505060e061402b8c828d01613dac565b92505061010061403d8c828d01613dac565b9150509295985092959850929598565b6140568161391f565b82525050565b5f60208201905061406f5f83018461404d565b92915050565b6004811061408657614085613ce0565b5b50565b5f81905061409682614075565b919050565b5f6140a582614089565b9050919050565b6140b58161409b565b82525050565b5f6060820190506140ce5f830186613cb3565b6140db6020830185613cd1565b6140e860408301846140ac565b949350505050565b5f805f805f8060a0878903121561410a57614109613812565b5b5f61411789828a01613946565b965050602061412889828a01613946565b955050604061413989828a01613979565b945050606061414a89828a01613979565b935050608087013567ffffffffffffffff81111561416b5761416a613816565b5b61417789828a01613b5c565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f6141f0602a83614186565b91506141fb82614196565b604082019050919050565b5f6020820190508181035f83015261421d816141e4565b9050919050565b5f819050919050565b61423e614239826138cd565b614224565b82525050565b5f61424f828461422d565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b5f5b8381101561428f578082015181840152602081019050614274565b5f8484015250505050565b5f6142a48261425e565b6142ae8185614268565b93506142be818560208601614272565b80840191505092915050565b5f6142d5828461429a565b915081905092915050565b5f815190506142ee816138d6565b92915050565b5f6020828403121561430957614308613812565b5b5f614316848285016142e0565b91505092915050565b5f8160601b9050919050565b5f6143358261431f565b9050919050565b5f6143468261432b565b9050919050565b61435e6143598261391f565b61433c565b82525050565b5f819050919050565b61437e6143798261395a565b614364565b82525050565b5f61438f828a61434d565b60148201915061439f828961434d565b6014820191506143af828861422d565b6020820191506143bf828761422d565b6020820191506143cf828661434d565b6014820191506143df828561436d565b6020820191506143ef828461436d565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f614438601383614186565b915061444382614404565b602082019050919050565b5f6020820190508181035f8301526144658161442c565b9050919050565b614475816138cd565b82525050565b5f60208201905061448e5f83018461446c565b92915050565b61449d8161395a565b82525050565b5f82825260208201905092915050565b50565b5f6144c15f836144a3565b91506144cc826144b3565b5f82019050919050565b5f60a0820190506144e95f83018761404d565b6144f6602083018661404d565b6145036040830185614494565b6145106060830184614494565b8181036080830152614521816144b6565b905095945050505050565b5f614537828961434d565b601482019150614547828861434d565b601482019150614557828761422d565b602082019150614567828661422d565b602082019150614577828561434d565b601482019150614587828461436d565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f6145f5603883614186565b91506146008261459b565b604082019050919050565b5f6020820190508181035f830152614622816145e9565b9050919050565b5f60608201905061463c5f83018661404d565b614649602083018561404d565b6146566040830184614494565b949350505050565b5f614669828a61436d565b602082019150614679828961436d565b602082019150614689828861434d565b601482019150614699828761434d565b6014820191506146a9828661422d565b6020820191506146b9828561422d565b6020820191506146c9828461434d565b60148201915081905098975050505050505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b614728826146e2565b810181811067ffffffffffffffff82111715614747576147466146f2565b5b80604052505050565b5f614759613809565b9050614765828261471f565b919050565b5f60c0828403121561477f5761477e6146de565b5b61478960c0614750565b90505f614798848285016138ec565b5f8301525060206147ab84828501613946565b60208301525060406147bf84828501613946565b60408301525060606147d3848285016138ec565b60608301525060806147e7848285016138ec565b60808301525060a06147fb84828501613dac565b60a08301525092915050565b5f60c0828403121561481c5761481b613812565b5b5f6148298482850161476a565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f61488c602a83614186565b915061489782614832565b604082019050919050565b5f6020820190508181035f8301526148b981614880565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f6148f4601e83614186565b91506148ff826148c0565b602082019050919050565b5f6020820190508181035f830152614921816148e8565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f61495c601e83614186565b915061496782614928565b602082019050919050565b5f6020820190508181035f83015261498981614950565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f6149ea602383614186565b91506149f582614990565b604082019050919050565b5f6020820190508181035f830152614a17816149de565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f614a52601b83614186565b9150614a5d82614a1e565b602082019050919050565b5f6020820190508181035f830152614a7f81614a46565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f614aba601a83614186565b9150614ac582614a86565b602082019050919050565b5f6020820190508181035f830152614ae781614aae565b9050919050565b5f604082019050614b015f83018561446c565b614b0e602083018461446c565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614b4c8261395a565b9150614b578361395a565b9250828201905080821115614b6f57614b6e614b15565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e74206f722054616b6572417070726f7665640000000000602082015250565b5f614bcf603b83614186565b9150614bda82614b75565b604082019050919050565b5f6020820190508181035f830152614bfc81614bc3565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e74207072652d617070726f7665206c6f636b2074696d65000000602082015250565b5f614c5d603d83614186565b9150614c6882614c03565b604082019050919050565b5f6020820190508181035f830152614c8a81614c51565b9050919050565b7f54616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f614ceb602483614186565b9150614cf682614c91565b604082019050919050565b5f6020820190508181035f830152614d1881614cdf565b9050919050565b7f5265636569766572206d757374206e6f74206265207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f614d79602183614186565b9150614d8482614d1f565b604082019050919050565b5f6020820190508181035f830152614da681614d6d565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f614e07602383614186565b9150614e1282614dad565b604082019050919050565b5f6020820190508181035f830152614e3481614dfb565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e20645f8201527f6578206665650000000000000000000000000000000000000000000000000000602082015250565b5f614e95602683614186565b9150614ea082614e3b565b604082019050919050565b5f6020820190508181035f830152614ec281614e89565b9050919050565b5f614ed38261395a565b9150614ede8361395a565b9250828203905081811115614ef657614ef5614b15565b5b92915050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f614f30601d83614186565b9150614f3b82614efc565b602082019050919050565b5f6020820190508181035f830152614f5d81614f24565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f614f98601583614186565b9150614fa382614f64565b602082019050919050565b5f6020820190508181035f830152614fc581614f8c565b9050919050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520545f8201527f616b6572417070726f7665640000000000000000000000000000000000000000602082015250565b5f615026602c83614186565b915061503182614fcc565b604082019050919050565b5f6020820190508181035f8301526150538161501a565b9050919050565b7f4552433230207632207061796d656e7420697320616c726561647920696e69745f8201527f69616c697a656400000000000000000000000000000000000000000000000000602082015250565b5f6150b4602783614186565b91506150bf8261505a565b604082019050919050565b5f6020820190508181035f8301526150e1816150a8565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f61511c601783614186565b9150615127826150e8565b602082019050919050565b5f6020820190508181035f83015261514981615110565b9050919050565b7f44657820666565206d757374206e6f74206265207a65726f00000000000000005f82015250565b5f615184601883614186565b915061518f82615150565b602082019050919050565b5f6020820190508181035f8301526151b181615178565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f615212602b83614186565b915061521d826151b8565b604082019050919050565b5f6020820190508181035f83015261523f81615206565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f61527a601c83614186565b915061528582615246565b602082019050919050565b5f6020820190508181035f8301526152a78161526e565b9050919050565b5f6040820190506152c15f83018561404d565b6152ce6020830184614494565b9392505050565b6152de8161389a565b81146152e8575f80fd5b50565b5f815190506152f9816152d5565b92915050565b5f6020828403121561531457615313613812565b5b5f615321848285016152eb565b9150509291505056fea26469706673582212200d86b0f6898fb823c55626c3b02a7098bc8622606b092e0f458df6c86ce2967864736f6c63430008180033 \ No newline at end of file diff --git a/mm2src/mm2_test_helpers/contract_bytes/swap_contract_bytes b/mm2src/mm2_test_helpers/contract_bytes/swap_contract_bytes new file mode 100644 index 0000000000..fea8557914 --- /dev/null +++ b/mm2src/mm2_test_helpers/contract_bytes/swap_contract_bytes @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50611437806100206000396000f3fe60806040526004361061004a5760003560e01c806302ed292b1461004f5780630716326d146100de578063152cf3af1461017b57806346fc0294146101f65780639b415b2a14610294575b600080fd5b34801561005b57600080fd5b506100dc600480360360a081101561007257600080fd5b81019080803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610339565b005b3480156100ea57600080fd5b506101176004803603602081101561010157600080fd5b8101908080359060200190929190505050610867565b60405180846bffffffffffffffffffffffff19166bffffffffffffffffffffffff191681526020018367ffffffffffffffff1667ffffffffffffffff16815260200182600381111561016557fe5b60ff168152602001935050505060405180910390f35b6101f46004803603608081101561019157600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080356bffffffffffffffffffffffff19169060200190929190803567ffffffffffffffff1690602001909291905050506108bf565b005b34801561020257600080fd5b50610292600480360360a081101561021957600080fd5b81019080803590602001909291908035906020019092919080356bffffffffffffffffffffffff19169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bd9565b005b610337600480360360c08110156102aa57600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080356bffffffffffffffffffffffff19169060200190929190803567ffffffffffffffff169060200190929190505050610fe2565b005b6001600381111561034657fe5b600080878152602001908152602001600020600001601c9054906101000a900460ff16600381111561037457fe5b1461037e57600080fd5b6000600333836003600288604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b602083106103db57805182526020820191506020810190506020830392506103b8565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa15801561041d573d6000803e3d6000fd5b5050506040513d602081101561043257600080fd5b8101908080519060200190929190505050604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b602083106104955780518252602082019150602081019050602083039250610472565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa1580156104d7573d6000803e3d6000fd5b5050506040515160601b8689604051602001808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401846bffffffffffffffffffffffff19166bffffffffffffffffffffffff191681526014018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401828152602001955050505050506040516020818303038152906040526040518082805190602001908083835b602083106105fc57805182526020820191506020810190506020830392506105d9565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa15801561063e573d6000803e3d6000fd5b5050506040515160601b905060008087815260200190815260200160002060000160009054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461069657600080fd5b6002600080888152602001908152602001600020600001601c6101000a81548160ff021916908360038111156106c857fe5b0217905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561074e573373ffffffffffffffffffffffffffffffffffffffff166108fc869081150290604051600060405180830381858888f19350505050158015610748573d6000803e3d6000fd5b50610820565b60008390508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33886040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156107da57600080fd5b505af11580156107ee573d6000803e3d6000fd5b505050506040513d602081101561080457600080fd5b810190808051906020019092919050505061081e57600080fd5b505b7f36c177bcb01c6d568244f05261e2946c8c977fa50822f3fa098c470770ee1f3e8685604051808381526020018281526020019250505060405180910390a1505050505050565b60006020528060005260406000206000915090508060000160009054906101000a900460601b908060000160149054906101000a900467ffffffffffffffff169080600001601c9054906101000a900460ff16905083565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156108fc5750600034115b801561094057506000600381111561091057fe5b600080868152602001908152602001600020600001601c9054906101000a900460ff16600381111561093e57fe5b145b61094957600080fd5b60006003843385600034604051602001808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401846bffffffffffffffffffffffff19166bffffffffffffffffffffffff191681526014018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401828152602001955050505050506040516020818303038152906040526040518082805190602001908083835b60208310610a6c5780518252602082019150602081019050602083039250610a49565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610aae573d6000803e3d6000fd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018367ffffffffffffffff16815260200160016003811115610af757fe5b81525060008087815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c021790555060208201518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550604082015181600001601c6101000a81548160ff02191690836003811115610b9357fe5b02179055509050507fccc9c05183599bd3135da606eaaf535daffe256e9de33c048014cffcccd4ad57856040518082815260200191505060405180910390a15050505050565b60016003811115610be657fe5b600080878152602001908152602001600020600001601c9054906101000a900460ff166003811115610c1457fe5b14610c1e57600080fd5b600060038233868689604051602001808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401846bffffffffffffffffffffffff19166bffffffffffffffffffffffff191681526014018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401828152602001955050505050506040516020818303038152906040526040518082805190602001908083835b60208310610d405780518252602082019150602081019050602083039250610d1d565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610d82573d6000803e3d6000fd5b5050506040515160601b905060008087815260200190815260200160002060000160009054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916148015610e10575060008087815260200190815260200160002060000160149054906101000a900467ffffffffffffffff1667ffffffffffffffff164210155b610e1957600080fd5b6003600080888152602001908152602001600020600001601c6101000a81548160ff02191690836003811115610e4b57fe5b0217905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610ed1573373ffffffffffffffffffffffffffffffffffffffff166108fc869081150290604051600060405180830381858888f19350505050158015610ecb573d6000803e3d6000fd5b50610fa3565b60008390508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33886040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610f5d57600080fd5b505af1158015610f71573d6000803e3d6000fd5b505050506040513d6020811015610f8757600080fd5b8101908080519060200190929190505050610fa157600080fd5b505b7f1797d500133f8e427eb9da9523aa4a25cb40f50ebc7dbda3c7c81778973f35ba866040518082815260200191505060405180910390a1505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561101f5750600085115b801561106357506000600381111561103357fe5b600080888152602001908152602001600020600001601c9054906101000a900460ff16600381111561106157fe5b145b61106c57600080fd5b60006003843385888a604051602001808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401846bffffffffffffffffffffffff19166bffffffffffffffffffffffff191681526014018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401828152602001955050505050506040516020818303038152906040526040518082805190602001908083835b6020831061118e578051825260208201915060208101905060208303925061116b565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa1580156111d0573d6000803e3d6000fd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018367ffffffffffffffff1681526020016001600381111561121957fe5b81525060008089815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c021790555060208201518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550604082015181600001601c6101000a81548160ff021916908360038111156112b557fe5b021790555090505060008590508073ffffffffffffffffffffffffffffffffffffffff166323b872dd33308a6040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561137d57600080fd5b505af1158015611391573d6000803e3d6000fd5b505050506040513d60208110156113a757600080fd5b81019080805190602001909291905050506113c157600080fd5b7fccc9c05183599bd3135da606eaaf535daffe256e9de33c048014cffcccd4ad57886040518082815260200191505060405180910390a1505050505050505056fea265627a7a723158208c83db436905afce0b7be1012be64818c49323c12d451fe2ab6bce76ff6421c964736f6c63430005110032 \ No newline at end of file diff --git a/mm2src/mm2_test_helpers/contract_bytes/taker_swap_v2_bytes b/mm2src/mm2_test_helpers/contract_bytes/taker_swap_v2_bytes new file mode 100644 index 0000000000..5394d75e8a --- /dev/null +++ b/mm2src/mm2_test_helpers/contract_bytes/taker_swap_v2_bytes @@ -0,0 +1 @@ +60a060405234801561000f575f80fd5b50604051612a1b380380612a1b83398181016040528101906100319190610137565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361009f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610096906101e2565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505050610200565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610106826100dd565b9050919050565b610116816100fc565b8114610120575f80fd5b50565b5f815190506101318161010d565b92915050565b5f6020828403121561014c5761014b6100d9565b5b5f61015984828501610123565b91505092915050565b5f82825260208201905092915050565b7f66656541646472657373206d757374206e6f74206265207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f6101cc602383610162565b91506101d782610172565b604082019050919050565b5f6020820190508181035f8301526101f9816101c0565b9050919050565b6080516127f56102265f395f818161116d0152818161120801526115c401526127f55ff3fe60806040526004361061007a575f3560e01c80639b4603f21161004d5780639b4603f214610135578063cc90c19914610151578063d6a71eb414610179578063e06cf966146101a15761007a565b8063146e5b241461007e5780633e6af5f2146100a657806346b95ac7146100ce57806365e266171461010d575b5f80fd5b348015610089575f80fd5b506100a4600480360381019061009f91906119ef565b6101cb565b005b3480156100b1575f80fd5b506100cc60048036038101906100c791906119ef565b6103ae565b005b3480156100d9575f80fd5b506100f460048036038101906100ef9190611a8c565b6106bc565b6040516101049493929190611b82565b60405180910390f35b348015610118575f80fd5b50610133600480360381019061012e91906119ef565b61071d565b005b61014f600480360381019061014a9190611bef565b610b79565b005b34801561015c575f80fd5b50610177600480360381019061017291906119ef565b610ead565b005b348015610184575f80fd5b5061019f600480360381019061019a9190611c8c565b61125a565b005b3480156101ac575f80fd5b506101b56115c2565b6040516101c29190611d5f565b60405180910390f35b600160048111156101df576101de611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff16600481111561021157610210611b0f565b5b14610251576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024890611df8565b60405180910390fd5b5f6003878787338888886040516020016102719796959493929190611e9b565b60405160208183030381529060405260405161028d9190611f6d565b602060405180830381855afa1580156102a8573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610332576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032990611fcd565b60405180910390fd5b60025f808a81526020019081526020015f205f01601c6101000a81548160ff0219169083600481111561036857610367611b0f565b5b02179055507f9c45e43e2ef051f70491ffd5221bf02ab37e1324128714ef9610df5f24fc9fb58860405161039c9190611ffa565b60405180910390a15050505050505050565b600160048111156103c2576103c1611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660048111156103f4576103f3611b0f565b5b14610434576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042b90611df8565b60405180910390fd5b5f60038787873360028960405160200161044e9190612013565b60405160208183030381529060405260405161046a9190611f6d565b602060405180830381855afa158015610485573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906104a89190612041565b88886040516020016104c09796959493929190611e9b565b6040516020818303038152906040526040516104dc9190611f6d565b602060405180830381855afa1580156104f7573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610581576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057890611fcd565b60405180910390fd5b60045f808a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156105b7576105b6611b0f565b5b02179055507f45169a52eef651b20a81474b50b8a5d83225225fcd097ef3cf7952d9ab304f2788856040516105ed92919061206c565b60405180910390a15f868861060291906120c0565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610680573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f1935050505015801561067a573d5f803e3d5ffd5b506106b1565b5f8390506106af33838373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900463ffffffff1690805f01601c9054906101000a900460ff16905084565b6001600481111561073157610730611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff16600481111561076357610762611b0f565b5b14806107b257506002600481111561077e5761077d611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660048111156107b0576107af611b0f565b5b145b6107f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e890612163565b60405180910390fd5b5f6003878787338888886040516020016108119796959493929190611e9b565b60405160208183030381529060405260405161082d9190611f6d565b602060405180830381855afa158015610848573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146108d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c990611fcd565b60405180910390fd5b600260048111156108e6576108e5611b0f565b5b5f808a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561091857610917611b0f565b5b03610989575f808981526020019081526020015f205f0160189054906101000a900463ffffffff1663ffffffff16421015610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097f906121f1565b60405180910390fd5b5b6001600481111561099d5761099c611b0f565b5b5f808a81526020019081526020015f205f01601c9054906101000a900460ff1660048111156109cf576109ce611b0f565b5b03610a40575f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610a3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a369061227f565b60405180910390fd5b5b60045f808a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610a7657610a75611b0f565b5b02179055507fbdd7a4be6d82798a500b59077706b12d3f45acf5504828919f92501307b2b95388604051610aaa9190611ffa565b60405180910390a15f8688610abf91906120c0565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b3d573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015610b37573d5f803e3d5ffd5b50610b6e565b5f839050610b6c33838373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b505050505050505050565b5f6004811115610b8c57610b8b611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff166004811115610bbe57610bbd611b0f565b5b14610bfe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf59061230d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610c6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c639061239b565b60405180910390fd5b5f3411610cae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca590612429565b60405180910390fd5b853411610cf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce7906124b7565b60405180910390fd5b5f60038734610cff91906124d5565b88883389895f604051602001610d1b9796959493929190611e9b565b604051602081830303815290604052604051610d379190611f6d565b602060405180830381855afa158015610d52573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115610daa57610da9611b0f565b5b8152505f808a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115610e6457610e63611b0f565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd93588604051610e9b9190611ffa565b60405180910390a15050505050505050565b60026004811115610ec157610ec0611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff166004811115610ef357610ef2611b0f565b5b14610f33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2a90612578565b60405180910390fd5b5f60038787338888600289604051602001610f4e9190612013565b604051602081830303815290604052604051610f6a9190611f6d565b602060405180830381855afa158015610f85573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610fa89190612041565b88604051602001610fbf9796959493929190611e9b565b604051602081830303815290604052604051610fdb9190611f6d565b602060405180830381855afa158015610ff6573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611080576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107790611fcd565b60405180910390fd5b60035f808a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156110b6576110b5611b0f565b5b02179055507f0d0da0df275f85bed3a5fe7ae79f3559341a3f9ccd8e010133438135bda00a8788846040516110ec92919061206c565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111d4573373ffffffffffffffffffffffffffffffffffffffff166108fc8890811502906040515f60405180830381858888f1935050505015801561116a573d5f803e3d5ffd5b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f193505050501580156111ce573d5f803e3d5ffd5b50611250565b5f82905061120333898373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b61124e7f0000000000000000000000000000000000000000000000000000000000000000888373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b5050505050505050565b5f600481111561126d5761126c611b0f565b5b5f808b81526020019081526020015f205f01601c9054906101000a900460ff16600481111561129f5761129e611b0f565b5b146112df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d690612606565b60405180910390fd5b5f8811611321576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113189061266e565b60405180910390fd5b5f8711611363576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135a906126d6565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c89061239b565b60405180910390fd5b5f60038989883389898d6040516020016113f19796959493929190611e9b565b60405160208183030381529060405260405161140d9190611f6d565b602060405180830381855afa158015611428573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff168152602001600160048111156114805761147f611b0f565b5b8152505f808c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff0219169083600481111561153a57611539611b0f565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358a6040516115719190611ffa565b60405180910390a15f8790506115b533308b8d61158e91906120c0565b8473ffffffffffffffffffffffffffffffffffffffff16611665909392919063ffffffff16565b5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b611660838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401611619929190612703565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506116e7565b505050565b6116e1848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161169a9392919061272a565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506116e7565b50505050565b5f611711828473ffffffffffffffffffffffffffffffffffffffff1661177c90919063ffffffff16565b90505f8151141580156117355750808060200190518101906117339190612794565b155b1561177757826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161176e9190611d5f565b60405180910390fd5b505050565b606061178983835f611791565b905092915050565b6060814710156117d857306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016117cf9190611d5f565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516118009190611f6d565b5f6040518083038185875af1925050503d805f811461183a576040519150601f19603f3d011682016040523d82523d5f602084013e61183f565b606091505b509150915061184f86838361185a565b925050509392505050565b60608261186f5761186a826118e7565b6118df565b5f825114801561189557505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156118d757836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016118ce9190611d5f565b60405180910390fd5b8190506118e0565b5b9392505050565b5f815111156118f95780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80fd5b5f819050919050565b6119418161192f565b811461194b575f80fd5b50565b5f8135905061195c81611938565b92915050565b5f819050919050565b61197481611962565b811461197e575f80fd5b50565b5f8135905061198f8161196b565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6119be82611995565b9050919050565b6119ce816119b4565b81146119d8575f80fd5b50565b5f813590506119e9816119c5565b92915050565b5f805f805f805f60e0888a031215611a0a57611a0961192b565b5b5f611a178a828b0161194e565b9750506020611a288a828b01611981565b9650506040611a398a828b01611981565b9550506060611a4a8a828b016119db565b9450506080611a5b8a828b0161194e565b93505060a0611a6c8a828b0161194e565b92505060c0611a7d8a828b016119db565b91505092959891949750929550565b5f60208284031215611aa157611aa061192b565b5b5f611aae8482850161194e565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b611aeb81611ab7565b82525050565b5f63ffffffff82169050919050565b611b0981611af1565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60058110611b4d57611b4c611b0f565b5b50565b5f819050611b5d82611b3c565b919050565b5f611b6c82611b50565b9050919050565b611b7c81611b62565b82525050565b5f608082019050611b955f830187611ae2565b611ba26020830186611b00565b611baf6040830185611b00565b611bbc6060830184611b73565b95945050505050565b611bce81611af1565b8114611bd8575f80fd5b50565b5f81359050611be981611bc5565b92915050565b5f805f805f805f60e0888a031215611c0a57611c0961192b565b5b5f611c178a828b0161194e565b9750506020611c288a828b01611981565b9650506040611c398a828b016119db565b9550506060611c4a8a828b0161194e565b9450506080611c5b8a828b0161194e565b93505060a0611c6c8a828b01611bdb565b92505060c0611c7d8a828b01611bdb565b91505092959891949750929550565b5f805f805f805f805f6101208a8c031215611caa57611ca961192b565b5b5f611cb78c828d0161194e565b9950506020611cc88c828d01611981565b9850506040611cd98c828d01611981565b9750506060611cea8c828d016119db565b9650506080611cfb8c828d016119db565b95505060a0611d0c8c828d0161194e565b94505060c0611d1d8c828d0161194e565b93505060e0611d2e8c828d01611bdb565b925050610100611d408c828d01611bdb565b9150509295985092959850929598565b611d59816119b4565b82525050565b5f602082019050611d725f830184611d50565b92915050565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f611de2602a83611d78565b9150611ded82611d88565b604082019050919050565b5f6020820190508181035f830152611e0f81611dd6565b9050919050565b5f819050919050565b611e30611e2b82611962565b611e16565b82525050565b5f8160601b9050919050565b5f611e4c82611e36565b9050919050565b5f611e5d82611e42565b9050919050565b611e75611e70826119b4565b611e53565b82525050565b5f819050919050565b611e95611e908261192f565b611e7b565b82525050565b5f611ea6828a611e1f565b602082019150611eb68289611e1f565b602082019150611ec68288611e64565b601482019150611ed68287611e64565b601482019150611ee68286611e84565b602082019150611ef68285611e84565b602082019150611f068284611e64565b60148201915081905098975050505050505050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f611f4782611f1b565b611f518185611f25565b9350611f61818560208601611f2f565b80840191505092915050565b5f611f788284611f3d565b915081905092915050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f611fb7601383611d78565b9150611fc282611f83565b602082019050919050565b5f6020820190508181035f830152611fe481611fab565b9050919050565b611ff48161192f565b82525050565b5f60208201905061200d5f830184611feb565b92915050565b5f61201e8284611e84565b60208201915081905092915050565b5f8151905061203b81611938565b92915050565b5f602082840312156120565761205561192b565b5b5f6120638482850161202d565b91505092915050565b5f60408201905061207f5f830185611feb565b61208c6020830184611feb565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6120ca82611962565b91506120d583611962565b92508282019050808211156120ed576120ec612093565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e74206f722054616b6572417070726f7665640000000000602082015250565b5f61214d603b83611d78565b9150612158826120f3565b604082019050919050565b5f6020820190508181035f83015261217a81612141565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f6121db603883611d78565b91506121e682612181565b604082019050919050565b5f6020820190508181035f830152612208816121cf565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e74207072652d617070726f7665206c6f636b2074696d65000000602082015250565b5f612269603d83611d78565b91506122748261220f565b604082019050919050565b5f6020820190508181035f8301526122968161225d565b9050919050565b7f54616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f6122f7602483611d78565b91506123028261229d565b604082019050919050565b5f6020820190508181035f830152612324816122eb565b9050919050565b7f5265636569766572206d757374206e6f74206265207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f612385602183611d78565b91506123908261232b565b604082019050919050565b5f6020820190508181035f8301526123b281612379565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f612413602383611d78565b915061241e826123b9565b604082019050919050565b5f6020820190508181035f83015261244081612407565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e20645f8201527f6578206665650000000000000000000000000000000000000000000000000000602082015250565b5f6124a1602683611d78565b91506124ac82612447565b604082019050919050565b5f6020820190508181035f8301526124ce81612495565b9050919050565b5f6124df82611962565b91506124ea83611962565b925082820390508181111561250257612501612093565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520545f8201527f616b6572417070726f7665640000000000000000000000000000000000000000602082015250565b5f612562602c83611d78565b915061256d82612508565b604082019050919050565b5f6020820190508181035f83015261258f81612556565b9050919050565b7f4552433230207632207061796d656e7420697320616c726561647920696e69745f8201527f69616c697a656400000000000000000000000000000000000000000000000000602082015250565b5f6125f0602783611d78565b91506125fb82612596565b604082019050919050565b5f6020820190508181035f83015261261d816125e4565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f612658601783611d78565b915061266382612624565b602082019050919050565b5f6020820190508181035f8301526126858161264c565b9050919050565b7f44657820666565206d757374206e6f74206265207a65726f00000000000000005f82015250565b5f6126c0601883611d78565b91506126cb8261268c565b602082019050919050565b5f6020820190508181035f8301526126ed816126b4565b9050919050565b6126fd81611962565b82525050565b5f6040820190506127165f830185611d50565b61272360208301846126f4565b9392505050565b5f60608201905061273d5f830186611d50565b61274a6020830185611d50565b61275760408301846126f4565b949350505050565b5f8115159050919050565b6127738161275f565b811461277d575f80fd5b50565b5f8151905061278e8161276a565b92915050565b5f602082840312156127a9576127a861192b565b5b5f6127b684828501612780565b9150509291505056fea2646970667358221220fd2a736cddd6ebbd2831b0e65fb5470ffebd789dc32c1d3782ce69362e16fae564736f6c63430008190033 \ No newline at end of file diff --git a/mm2src/mm2_test_helpers/contract_bytes/watchers_swap_contract_bytes b/mm2src/mm2_test_helpers/contract_bytes/watchers_swap_contract_bytes new file mode 100644 index 0000000000..1b00a95ba1 --- /dev/null +++ b/mm2src/mm2_test_helpers/contract_bytes/watchers_swap_contract_bytes @@ -0,0 +1 @@ +608060405234801561000f575f80fd5b50612aa48061001d5f395ff3fe608060405260043610610085575f3560e01c806346fc02941161005857806346fc0294146101275780636a3227861461014f5780639b415b2a1461016b578063b5985c4d14610193578063cd1dde34146101bb57610085565b806302ed292b146100895780630716326d146100b15780630971fd54146100ef578063152cf3af1461010b575b5f80fd5b348015610094575f80fd5b506100af60048036038101906100aa9190611e1d565b6101e3565b005b3480156100bc575f80fd5b506100d760048036038101906100d29190611e94565b610518565b6040516100e693929190611f8e565b60405180910390f35b6101096004803603810190610104919061206f565b610568565b005b6101256004803603810190610120919061210c565b610787565b005b348015610132575f80fd5b5061014d60048036038101906101489190612170565b61099d565b005b610169600480360381019061016491906121e7565b610c4d565b005b348015610176575f80fd5b50610191600480360381019061018c91906122ab565b610f61565b005b34801561019e575f80fd5b506101b960048036038101906101b49190612334565b611203565b005b3480156101c6575f80fd5b506101e160048036038101906101dc91906123f8565b611887565b005b600160038111156101f7576101f6611f1b565b5b5f808781526020019081526020015f205f01601c9054906101000a900460ff16600381111561022957610228611f1b565b5b14610232575f80fd5b5f60033383600360028860405160200161024c91906124dc565b6040516020818303038152906040526040516102689190612562565b602060405180830381855afa158015610283573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906102a6919061258c565b6040516020016102b691906124dc565b6040516020818303038152906040526040516102d29190612562565b602060405180830381855afa1580156102ed573d5f803e3d5ffd5b5050506040515160601b868960405160200161030d95949392919061263c565b6040516020818303038152906040526040516103299190612562565b602060405180830381855afa158015610344573d5f803e3d5ffd5b5050506040515160601b90505f808781526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610397575f80fd5b60025f808881526020019081526020015f205f01601c6101000a81548160ff021916908360038111156103cd576103cc611f1b565b5b02179055505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361044e573373ffffffffffffffffffffffffffffffffffffffff166108fc8690811502906040515f60405180830381858888f19350505050158015610448573d5f803e3d5ffd5b506104d7565b5f8390508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33886040518363ffffffff1660e01b815260040161048d9291906126b8565b6020604051808303815f875af11580156104a9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104cd91906126f3565b6104d5575f80fd5b505b7f36c177bcb01c6d568244f05261e2946c8c977fa50822f3fa098c470770ee1f3e868560405161050892919061272d565b60405180910390a1505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900467ffffffffffffffff1690805f01601c9054906101000a900460ff16905083565b5f73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16141580156105a357505f34115b80156105f157505f60038111156105bd576105bc611f1b565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660038111156105ef576105ee611f1b565b5b145b6105f9575f80fd5b5f60038733885f3489898960405160200161061b9897969594939291906127e7565b6040516020818303038152906040526040516106379190612562565b602060405180830381855afa158015610652573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018667ffffffffffffffff168152602001600160038111156106a2576106a1611f1b565b5b8152505f808a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040820151815f01601c6101000a81548160ff0219169083600381111561073e5761073d611f1b565b5b02179055509050507fccc9c05183599bd3135da606eaaf535daffe256e9de33c048014cffcccd4ad57886040516107759190612878565b60405180910390a15050505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156107c257505f34115b801561081057505f60038111156107dc576107db611f1b565b5b5f808681526020019081526020015f205f01601c9054906101000a900460ff16600381111561080e5761080d611f1b565b5b145b610818575f80fd5b5f60038433855f3460405160200161083495949392919061263c565b6040516020818303038152906040526040516108509190612562565b602060405180830381855afa15801561086b573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018367ffffffffffffffff168152602001600160038111156108bb576108ba611f1b565b5b8152505f808781526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040820151815f01601c6101000a81548160ff0219169083600381111561095757610956611f1b565b5b02179055509050507fccc9c05183599bd3135da606eaaf535daffe256e9de33c048014cffcccd4ad578560405161098e9190612878565b60405180910390a15050505050565b600160038111156109b1576109b0611f1b565b5b5f808781526020019081526020015f205f01601c9054906101000a900460ff1660038111156109e3576109e2611f1b565b5b146109ec575f80fd5b5f60038233868689604051602001610a0895949392919061263c565b604051602081830303815290604052604051610a249190612562565b602060405180830381855afa158015610a3f573d5f803e3d5ffd5b5050506040515160601b90505f808781526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916148015610ac657505f808781526020019081526020015f205f0160149054906101000a900467ffffffffffffffff1667ffffffffffffffff164210155b610ace575f80fd5b60035f808881526020019081526020015f205f01601c6101000a81548160ff02191690836003811115610b0457610b03611f1b565b5b02179055505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b85573373ffffffffffffffffffffffffffffffffffffffff166108fc8690811502906040515f60405180830381858888f19350505050158015610b7f573d5f803e3d5ffd5b50610c0e565b5f8390508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33886040518363ffffffff1660e01b8152600401610bc49291906126b8565b6020604051808303815f875af1158015610be0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c0491906126f3565b610c0c575f80fd5b505b7f1797d500133f8e427eb9da9523aa4a25cb40f50ebc7dbda3c7c81778973f35ba86604051610c3d9190612878565b60405180910390a1505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614158015610c8857505f88115b8015610cd657505f6003811115610ca257610ca1611f1b565b5b5f808b81526020019081526020015f205f01601c9054906101000a900460ff166003811115610cd457610cd3611f1b565b5b145b610cde575f80fd5b5f6003811115610cf157610cf0611f1b565b5b836003811115610d0457610d03611f1b565b5b14158015610d365750600380811115610d2057610d1f611f1b565b5b836003811115610d3357610d32611f1b565b5b14155b15610d4757803414610d46575f80fd5b5b5f60038733888b8d898989604051602001610d699897969594939291906127e7565b604051602081830303815290604052604051610d859190612562565b602060405180830381855afa158015610da0573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018667ffffffffffffffff16815260200160016003811115610df057610def611f1b565b5b8152505f808c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040820151815f01601c6101000a81548160ff02191690836003811115610e8c57610e8b611f1b565b5b02179055509050505f8890508073ffffffffffffffffffffffffffffffffffffffff166323b872dd33308d6040518463ffffffff1660e01b8152600401610ed593929190612891565b6020604051808303815f875af1158015610ef1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f1591906126f3565b610f1d575f80fd5b7fccc9c05183599bd3135da606eaaf535daffe256e9de33c048014cffcccd4ad578b604051610f4c9190612878565b60405180910390a15050505050505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015610f9c57505f85115b8015610fea57505f6003811115610fb657610fb5611f1b565b5b5f808881526020019081526020015f205f01601c9054906101000a900460ff166003811115610fe857610fe7611f1b565b5b145b610ff2575f80fd5b5f6003843385888a60405160200161100e95949392919061263c565b60405160208183030381529060405260405161102a9190612562565b602060405180830381855afa158015611045573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018367ffffffffffffffff1681526020016001600381111561109557611094611f1b565b5b8152505f808981526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040820151815f01601c6101000a81548160ff0219169083600381111561113157611130611f1b565b5b02179055509050505f8590508073ffffffffffffffffffffffffffffffffffffffff166323b872dd33308a6040518463ffffffff1660e01b815260040161117a93929190612891565b6020604051808303815f875af1158015611196573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ba91906126f3565b6111c2575f80fd5b7fccc9c05183599bd3135da606eaaf535daffe256e9de33c048014cffcccd4ad57886040516111f19190612878565b60405180910390a15050505050505050565b6001600381111561121757611216611f1b565b5b5f808b81526020019081526020015f205f01601c9054906101000a900460ff16600381111561124957611248611f1b565b5b14611289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128090612920565b60405180910390fd5b5f60038587600360028c6040516020016112a391906124dc565b6040516020818303038152906040526040516112bf9190612562565b602060405180830381855afa1580156112da573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906112fd919061258c565b60405160200161130d91906124dc565b6040516020818303038152906040526040516113299190612562565b602060405180830381855afa158015611344573d5f803e3d5ffd5b5050506040515160601b8a8d89898960405160200161136a9897969594939291906127e7565b6040516020818303038152906040526040516113869190612562565b602060405180830381855afa1580156113a1573d5f803e3d5ffd5b5050506040515160601b90505f808b81526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461142b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142290612988565b60405180910390fd5b60025f808c81526020019081526020015f205f01601c6101000a81548160ff0219169083600381111561146157611460611f1b565b5b02179055505f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff160361159e575f8060038111156114ad576114ac611f1b565b5b8560038111156114c0576114bf611f1b565b5b1480156114cb575083155b6114e057828a6114db91906129d3565b6114e2565b895b90508573ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015611527573d5f803e3d5ffd5b5060038081111561153b5761153a611f1b565b5b85600381111561154e5761154d611f1b565b5b03611598573373ffffffffffffffffffffffffffffffffffffffff166108fc8490811502906040515f60405180830381858888f19350505050158015611596573d5f803e3d5ffd5b505b50611786565b5f6003808111156115b2576115b1611f1b565b5b8560038111156115c5576115c4611f1b565b5b146115d057896115dd565b828a6115dc91906129d3565b5b90505f8890508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb88846040518363ffffffff1660e01b815260040161161e9291906126b8565b6020604051808303815f875af115801561163a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061165e91906126f3565b61169d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169490612a50565b60405180910390fd5b6003808111156116b0576116af611f1b565b5b8660038111156116c3576116c2611f1b565b5b03611783578073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33866040518363ffffffff1660e01b81526004016117039291906126b8565b6020604051808303815f875af115801561171f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061174391906126f3565b611782576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177990612a50565b60405180910390fd5b5b50505b6002600381111561179a57611799611f1b565b5b8460038111156117ad576117ac611f1b565b5b036117f7578573ffffffffffffffffffffffffffffffffffffffff166108fc8390811502906040515f60405180830381858888f193505050501580156117f5573d5f803e3d5ffd5b505b8215611842573373ffffffffffffffffffffffffffffffffffffffff166108fc8390811502906040515f60405180830381858888f19350505050158015611840573d5f803e3d5ffd5b505b7f36c177bcb01c6d568244f05261e2946c8c977fa50822f3fa098c470770ee1f3e8a8960405161187392919061272d565b60405180910390a150505050505050505050565b6001600381111561189b5761189a611f1b565b5b5f808b81526020019081526020015f205f01601c9054906101000a900460ff1660038111156118cd576118cc611f1b565b5b146118d6575f80fd5b5f600385878a8a8d8989896040516020016118f89897969594939291906127e7565b6040516020818303038152906040526040516119149190612562565b602060405180830381855afa15801561192f573d5f803e3d5ffd5b5050506040515160601b90505f808b81526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161480156119b657505f808b81526020019081526020015f205f0160149054906101000a900467ffffffffffffffff1667ffffffffffffffff164210155b6119be575f80fd5b60035f808c81526020019081526020015f205f01601c6101000a81548160ff021916908360038111156119f4576119f3611f1b565b5b02179055505f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1603611b27575f806003811115611a4057611a3f611f1b565b5b856003811115611a5357611a52611f1b565b5b14611a6957828a611a6491906129d3565b611a6b565b895b90508673ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015611ab0573d5f803e3d5ffd5b505f6003811115611ac457611ac3611f1b565b5b856003811115611ad757611ad6611f1b565b5b14611b21573373ffffffffffffffffffffffffffffffffffffffff166108fc8490811502906040515f60405180830381858888f19350505050158015611b1f573d5f803e3d5ffd5b505b50611d16565b5f600380811115611b3b57611b3a611f1b565b5b856003811115611b4e57611b4d611f1b565b5b14611b595789611b66565b828a611b6591906129d3565b5b90505f8890508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb89846040518363ffffffff1660e01b8152600401611ba79291906126b8565b6020604051808303815f875af1158015611bc3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611be791906126f3565b611bef575f80fd5b600380811115611c0257611c01611f1b565b5b866003811115611c1557611c14611f1b565b5b03611ca2578073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33866040518363ffffffff1660e01b8152600401611c559291906126b8565b6020604051808303815f875af1158015611c71573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c9591906126f3565b611c9d575f80fd5b611d13565b5f6003811115611cb557611cb4611f1b565b5b866003811115611cc857611cc7611f1b565b5b14611d12573373ffffffffffffffffffffffffffffffffffffffff166108fc8590811502906040515f60405180830381858888f19350505050158015611d10573d5f803e3d5ffd5b505b5b50505b7f1797d500133f8e427eb9da9523aa4a25cb40f50ebc7dbda3c7c81778973f35ba8a604051611d459190612878565b60405180910390a150505050505050505050565b5f80fd5b5f819050919050565b611d6f81611d5d565b8114611d79575f80fd5b50565b5f81359050611d8a81611d66565b92915050565b5f819050919050565b611da281611d90565b8114611dac575f80fd5b50565b5f81359050611dbd81611d99565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611dec82611dc3565b9050919050565b611dfc81611de2565b8114611e06575f80fd5b50565b5f81359050611e1781611df3565b92915050565b5f805f805f60a08688031215611e3657611e35611d59565b5b5f611e4388828901611d7c565b9550506020611e5488828901611daf565b9450506040611e6588828901611d7c565b9350506060611e7688828901611e09565b9250506080611e8788828901611e09565b9150509295509295909350565b5f60208284031215611ea957611ea8611d59565b5b5f611eb684828501611d7c565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b611ef381611ebf565b82525050565b5f67ffffffffffffffff82169050919050565b611f1581611ef9565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60048110611f5957611f58611f1b565b5b50565b5f819050611f6982611f48565b919050565b5f611f7882611f5c565b9050919050565b611f8881611f6e565b82525050565b5f606082019050611fa15f830186611eea565b611fae6020830185611f0c565b611fbb6040830184611f7f565b949350505050565b611fcc81611ebf565b8114611fd6575f80fd5b50565b5f81359050611fe781611fc3565b92915050565b611ff681611ef9565b8114612000575f80fd5b50565b5f8135905061201181611fed565b92915050565b60048110612023575f80fd5b50565b5f8135905061203481612017565b92915050565b5f8115159050919050565b61204e8161203a565b8114612058575f80fd5b50565b5f8135905061206981612045565b92915050565b5f805f805f805f60e0888a03121561208a57612089611d59565b5b5f6120978a828b01611d7c565b97505060206120a88a828b01611e09565b96505060406120b98a828b01611fd9565b95505060606120ca8a828b01612003565b94505060806120db8a828b01612026565b93505060a06120ec8a828b0161205b565b92505060c06120fd8a828b01611daf565b91505092959891949750929550565b5f805f806080858703121561212457612123611d59565b5b5f61213187828801611d7c565b945050602061214287828801611e09565b935050604061215387828801611fd9565b925050606061216487828801612003565b91505092959194509250565b5f805f805f60a0868803121561218957612188611d59565b5b5f61219688828901611d7c565b95505060206121a788828901611daf565b94505060406121b888828901611fd9565b93505060606121c988828901611e09565b92505060806121da88828901611e09565b9150509295509295909350565b5f805f805f805f805f6101208a8c03121561220557612204611d59565b5b5f6122128c828d01611d7c565b99505060206122238c828d01611daf565b98505060406122348c828d01611e09565b97505060606122458c828d01611e09565b96505060806122568c828d01611fd9565b95505060a06122678c828d01612003565b94505060c06122788c828d01612026565b93505060e06122898c828d0161205b565b92505061010061229b8c828d01611daf565b9150509295985092959850929598565b5f805f805f8060c087890312156122c5576122c4611d59565b5b5f6122d289828a01611d7c565b96505060206122e389828a01611daf565b95505060406122f489828a01611e09565b945050606061230589828a01611e09565b935050608061231689828a01611fd9565b92505060a061232789828a01612003565b9150509295509295509295565b5f805f805f805f805f6101208a8c03121561235257612351611d59565b5b5f61235f8c828d01611d7c565b99505060206123708c828d01611daf565b98505060406123818c828d01611d7c565b97505060606123928c828d01611e09565b96505060806123a38c828d01611e09565b95505060a06123b48c828d01611e09565b94505060c06123c58c828d01612026565b93505060e06123d68c828d0161205b565b9250506101006123e88c828d01611daf565b9150509295985092959850929598565b5f805f805f805f805f6101208a8c03121561241657612415611d59565b5b5f6124238c828d01611d7c565b99505060206124348c828d01611daf565b98505060406124458c828d01611fd9565b97505060606124568c828d01611e09565b96505060806124678c828d01611e09565b95505060a06124788c828d01611e09565b94505060c06124898c828d01612026565b93505060e061249a8c828d0161205b565b9250506101006124ac8c828d01611daf565b9150509295985092959850929598565b5f819050919050565b6124d66124d182611d5d565b6124bc565b82525050565b5f6124e782846124c5565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b5f5b8381101561252757808201518184015260208101905061250c565b5f8484015250505050565b5f61253c826124f6565b6125468185612500565b935061255681856020860161250a565b80840191505092915050565b5f61256d8284612532565b915081905092915050565b5f8151905061258681611d66565b92915050565b5f602082840312156125a1576125a0611d59565b5b5f6125ae84828501612578565b91505092915050565b5f8160601b9050919050565b5f6125cd826125b7565b9050919050565b5f6125de826125c3565b9050919050565b6125f66125f182611de2565b6125d4565b82525050565b5f819050919050565b61261661261182611ebf565b6125fc565b82525050565b5f819050919050565b61263661263182611d90565b61261c565b82525050565b5f61264782886125e5565b60148201915061265782876125e5565b6014820191506126678286612605565b60148201915061267782856125e5565b6014820191506126878284612625565b6020820191508190509695505050505050565b6126a381611de2565b82525050565b6126b281611d90565b82525050565b5f6040820190506126cb5f83018561269a565b6126d860208301846126a9565b9392505050565b5f815190506126ed81612045565b92915050565b5f6020828403121561270857612707611d59565b5b5f612715848285016126df565b91505092915050565b61272781611d5d565b82525050565b5f6040820190506127405f83018561271e565b61274d602083018461271e565b9392505050565b6004811061276557612764611f1b565b5b50565b5f81905061277582612754565b919050565b5f61278482612768565b9050919050565b5f8160f81b9050919050565b5f6127a18261278b565b9050919050565b6127b96127b48261277a565b612797565b82525050565b5f6127c982612797565b9050919050565b6127e16127dc8261203a565b6127bf565b82525050565b5f6127f2828b6125e5565b601482019150612802828a6125e5565b6014820191506128128289612605565b60148201915061282282886125e5565b6014820191506128328287612625565b60208201915061284282866127a8565b60018201915061285282856127d0565b6001820191506128628284612625565b6020820191508190509998505050505050505050565b5f60208201905061288b5f83018461271e565b92915050565b5f6060820190506128a45f83018661269a565b6128b1602083018561269a565b6128be60408301846126a9565b949350505050565b5f82825260208201905092915050565b7f5061796d656e7420776173206e6f742073656e740000000000000000000000005f82015250565b5f61290a6014836128c6565b9150612915826128d6565b602082019050919050565b5f6020820190508181035f830152612937816128fe565b9050919050565b7f496e76616c6964207061796d656e7420686173680000000000000000000000005f82015250565b5f6129726014836128c6565b915061297d8261293e565b602082019050919050565b5f6020820190508181035f83015261299f81612966565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6129dd82611d90565b91506129e883611d90565b9250828203905081811115612a00576129ff6129a6565b5b92915050565b7f546f6b656e207472616e73666572206661696c656400000000000000000000005f82015250565b5f612a3a6015836128c6565b9150612a4582612a06565b602082019050919050565b5f6020820190508181035f830152612a6781612a2e565b905091905056fea26469706673582212203106867e1b147b377237cde0aba42d82faf0282b83d7b6d62cca039d0b7f840564736f6c63430008160033 \ No newline at end of file From 8143cc2e61f0c08a7cba4a67644d15c076f6128c Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 20 Jun 2024 14:28:02 +0700 Subject: [PATCH 064/233] review: move code to EthCoinType::Nft arm --- mm2src/coins/eth/nft_swap_v2/mod.rs | 192 ++++++++++++++-------------- 1 file changed, 98 insertions(+), 94 deletions(-) diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index 74976662ec..a2a9032439 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -24,16 +24,16 @@ impl EthCoin { &self, args: SendNftMakerPaymentArgs<'_, Self>, ) -> Result { - try_tx_s!(validate_payment_args( - args.taker_secret_hash, - args.maker_secret_hash, - &args.amount, - args.nft_swap_info.contract_type - )); - let htlc_data = try_tx_s!(self.prepare_htlc_data(&args)); - match &self.coin_type { EthCoinType::Nft { .. } => { + try_tx_s!(validate_payment_args( + args.taker_secret_hash, + args.maker_secret_hash, + &args.amount, + args.nft_swap_info.contract_type + )); + let htlc_data = try_tx_s!(self.prepare_htlc_data(&args)); + let data = try_tx_s!(self.prepare_nft_maker_payment_v2_data(&args, htlc_data).await); self.sign_and_send_transaction( 0.into(), @@ -54,42 +54,44 @@ impl EthCoin { &self, args: ValidateNftMakerPaymentArgs<'_, Self>, ) -> ValidatePaymentResult<()> { - let contract_type = args.nft_swap_info.contract_type; - validate_payment_args( - args.taker_secret_hash, - args.maker_secret_hash, - &args.amount, - contract_type, - ) - .map_err(ValidatePaymentError::InternalError)?; - let etomic_swap_contract = args.nft_swap_info.swap_contract_address; - let token_address = args.nft_swap_info.token_address; - let maker_address = addr_from_raw_pubkey(args.maker_pub).map_to_mm(ValidatePaymentError::InternalError)?; - let time_lock_u32 = args - .time_lock - .try_into() - .map_err(ValidatePaymentError::TimelockOverflow)?; - let swap_id = self.etomic_swap_id(time_lock_u32, args.maker_secret_hash); - let maker_status = self - .payment_status_v2( - *etomic_swap_contract, - Token::FixedBytes(swap_id.clone()), - &NFT_MAKER_SWAP_V2, - PaymentType::MakerPayments, - ) - .await?; - let tx_from_rpc = self - .transaction(TransactionId::Hash(args.maker_payment_tx.tx_hash())) - .await?; - let tx_from_rpc = tx_from_rpc.as_ref().ok_or_else(|| { - ValidatePaymentError::TxDoesNotExist(format!( - "Didn't find provided tx {:?} on ETH node", - args.maker_payment_tx.tx_hash() - )) - })?; - validate_from_to_and_maker_status(tx_from_rpc, maker_address, *token_address, maker_status).await?; match self.coin_type { EthCoinType::Nft { .. } => { + let contract_type = args.nft_swap_info.contract_type; + validate_payment_args( + args.taker_secret_hash, + args.maker_secret_hash, + &args.amount, + contract_type, + ) + .map_err(ValidatePaymentError::InternalError)?; + let etomic_swap_contract = args.nft_swap_info.swap_contract_address; + let token_address = args.nft_swap_info.token_address; + let maker_address = + addr_from_raw_pubkey(args.maker_pub).map_to_mm(ValidatePaymentError::InternalError)?; + let time_lock_u32 = args + .time_lock + .try_into() + .map_err(ValidatePaymentError::TimelockOverflow)?; + let swap_id = self.etomic_swap_id(time_lock_u32, args.maker_secret_hash); + let maker_status = self + .payment_status_v2( + *etomic_swap_contract, + Token::FixedBytes(swap_id.clone()), + &NFT_MAKER_SWAP_V2, + PaymentType::MakerPayments, + ) + .await?; + let tx_from_rpc = self + .transaction(TransactionId::Hash(args.maker_payment_tx.tx_hash())) + .await?; + let tx_from_rpc = tx_from_rpc.as_ref().ok_or_else(|| { + ValidatePaymentError::TxDoesNotExist(format!( + "Didn't find provided tx {:?} on ETH node", + args.maker_payment_tx.tx_hash() + )) + })?; + validate_from_to_and_maker_status(tx_from_rpc, maker_address, *token_address, maker_status).await?; + let (decoded, bytes_index) = get_decoded_tx_data_and_bytes_index(contract_type, &tx_from_rpc.input.0)?; let amount = if matches!(contract_type, &ContractType::Erc1155) { @@ -131,27 +133,28 @@ impl EthCoin { &self, args: SpendNftMakerPaymentArgs<'_, Self>, ) -> Result { - let etomic_swap_contract = args.swap_contract_address; - if args.maker_secret.len() != 32 { - return Err(TransactionErr::Plain(ERRL!("maker_secret must be 32 bytes"))); - } - let (decoded, bytes_index) = try_tx_s!(get_decoded_tx_data_and_bytes_index( - args.contract_type, - args.maker_payment_tx.unsigned().data() - )); - - let (state, htlc_params) = try_tx_s!( - self.status_and_htlc_params_from_tx_data( - *etomic_swap_contract, - &NFT_MAKER_SWAP_V2, - &decoded, - bytes_index, - PaymentType::MakerPayments, - ) - .await - ); match self.coin_type { EthCoinType::Nft { .. } => { + let etomic_swap_contract = args.swap_contract_address; + if args.maker_secret.len() != 32 { + return Err(TransactionErr::Plain(ERRL!("maker_secret must be 32 bytes"))); + } + let (decoded, bytes_index) = try_tx_s!(get_decoded_tx_data_and_bytes_index( + args.contract_type, + args.maker_payment_tx.unsigned().data() + )); + + let (state, htlc_params) = try_tx_s!( + self.status_and_htlc_params_from_tx_data( + *etomic_swap_contract, + &NFT_MAKER_SWAP_V2, + &decoded, + bytes_index, + PaymentType::MakerPayments, + ) + .await + ); + let data = try_tx_s!(self.prepare_spend_nft_maker_v2_data(&args, decoded, htlc_params, state)); self.sign_and_send_transaction( 0.into(), @@ -172,24 +175,24 @@ impl EthCoin { &self, args: RefundNftMakerPaymentArgs<'_, Self>, ) -> Result { - let etomic_swap_contract = args.swap_contract_address; - let (decoded, bytes_index) = try_tx_s!(get_decoded_tx_data_and_bytes_index( - args.contract_type, - args.maker_payment_tx.unsigned().data() - )); - - let (state, htlc_params) = try_tx_s!( - self.status_and_htlc_params_from_tx_data( - *etomic_swap_contract, - &NFT_MAKER_SWAP_V2, - &decoded, - bytes_index, - PaymentType::MakerPayments, - ) - .await - ); match self.coin_type { EthCoinType::Nft { .. } => { + let etomic_swap_contract = args.swap_contract_address; + let (decoded, bytes_index) = try_tx_s!(get_decoded_tx_data_and_bytes_index( + args.contract_type, + args.maker_payment_tx.unsigned().data() + )); + + let (state, htlc_params) = try_tx_s!( + self.status_and_htlc_params_from_tx_data( + *etomic_swap_contract, + &NFT_MAKER_SWAP_V2, + &decoded, + bytes_index, + PaymentType::MakerPayments, + ) + .await + ); let data = try_tx_s!(self.prepare_refund_nft_maker_payment_v2_timelock(&args, decoded, htlc_params, state)); self.sign_and_send_transaction( @@ -211,24 +214,25 @@ impl EthCoin { &self, args: RefundNftMakerPaymentArgs<'_, Self>, ) -> Result { - let etomic_swap_contract = args.swap_contract_address; - let (decoded, bytes_index) = try_tx_s!(get_decoded_tx_data_and_bytes_index( - args.contract_type, - args.maker_payment_tx.unsigned().data() - )); - - let (state, htlc_params) = try_tx_s!( - self.status_and_htlc_params_from_tx_data( - *etomic_swap_contract, - &NFT_MAKER_SWAP_V2, - &decoded, - bytes_index, - PaymentType::MakerPayments, - ) - .await - ); match self.coin_type { EthCoinType::Nft { .. } => { + let etomic_swap_contract = args.swap_contract_address; + let (decoded, bytes_index) = try_tx_s!(get_decoded_tx_data_and_bytes_index( + args.contract_type, + args.maker_payment_tx.unsigned().data() + )); + + let (state, htlc_params) = try_tx_s!( + self.status_and_htlc_params_from_tx_data( + *etomic_swap_contract, + &NFT_MAKER_SWAP_V2, + &decoded, + bytes_index, + PaymentType::MakerPayments, + ) + .await + ); + let data = try_tx_s!(self.prepare_refund_nft_maker_payment_v2_secret(&args, decoded, htlc_params, state)); self.sign_and_send_transaction( @@ -614,7 +618,7 @@ async fn validate_from_to_and_maker_status( Ok(()) } -/// Identifies the correct "safeTransferFrom" function based on the contract type (either ERC1155 or ERC721) +/// Identifies the correct `"safeTransferFrom"` function based on the contract type (either ERC1155 or ERC721) /// and decodes the provided contract call bytes using the ABI of the identified function. Additionally, it returns /// the index position of the "bytes" field within the function's parameters. pub(crate) fn get_decoded_tx_data_and_bytes_index( From b391a164628c4fdaaac5c18602b097274018eb56 Mon Sep 17 00:00:00 2001 From: laruh Date: Sat, 22 Jun 2024 13:42:44 +0700 Subject: [PATCH 065/233] state machine: fix log info text related to sign_and_send_taker_funding_spend --- mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs index f91e98f2f6..83b67cf57f 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs @@ -1571,7 +1571,7 @@ impl Date: Sat, 22 Jun 2024 13:53:23 +0700 Subject: [PATCH 066/233] review: provide log!, instead println! in tests --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 9 +++++---- mm2src/mm2_main/tests/docker_tests_main.rs | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index d250a708b5..a61c0f2690 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -478,7 +478,7 @@ fn send_safe_transfer_from( ) .unwrap(); - println!("Transaction sent: {:?}", result); + log!("Transaction sent: {:?}", result); Ok(result) } @@ -879,12 +879,13 @@ fn wait_pending_transactions(wallet_address: Address) { let pending_nonce = block_on(web3.eth().transaction_count(wallet_address, Some(BlockNumber::Pending))).unwrap(); if latest_nonce == pending_nonce { - println!("All pending transactions have been confirmed."); + log!("All pending transactions have been confirmed."); break; } else { - println!( + log!( "Waiting for pending transactions to confirm... Current nonce: {}, Pending nonce: {}", - latest_nonce, pending_nonce + latest_nonce, + pending_nonce ); thread::sleep(Duration::from_secs(1)); } diff --git a/mm2src/mm2_main/tests/docker_tests_main.rs b/mm2src/mm2_main/tests/docker_tests_main.rs index 1584550024..100519d7f1 100644 --- a/mm2src/mm2_main/tests/docker_tests_main.rs +++ b/mm2src/mm2_main/tests/docker_tests_main.rs @@ -111,14 +111,14 @@ fn wait_for_geth_node_ready() { } match block_on(GETH_WEB3.eth().block_number().timeout(Duration::from_secs(6))) { Ok(Ok(block_number)) => { - println!("Geth node is ready, latest block number: {:?}", block_number); + log!("Geth node is ready, latest block number: {:?}", block_number); break; }, Ok(Err(e)) => { - println!("Failed to connect to Geth node: {:?}, retrying...", e); + log!("Failed to connect to Geth node: {:?}, retrying...", e); }, Err(_) => { - println!("Connection to Geth node timed out, retrying..."); + log!("Connection to Geth node timed out, retrying..."); }, } attempts += 1; From d9980622ac00f812bd23ef60b120234de0ab765c Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 23 Jun 2024 21:01:41 +0700 Subject: [PATCH 067/233] review: swap part of ERC1155 nfts in eth_docker_tests.rs --- .../tests/docker_tests/eth_docker_tests.rs | 51 ++++++++++++++----- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 09f065da5f..dca50e0042 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1031,14 +1031,20 @@ fn send_and_spend_erc1155_maker_payment() { time_lock, ); - let maker_payment = send_nft_maker_payment(&setup, amount.into()); + let maker_address = block_on(setup.maker_global_nft.my_addr()); + let maker_balance = geth_erc1155_balance(maker_address, U256::from(token_id)); + assert_eq!(U256::from(amount), maker_balance); + + let swap_amount = 2u32; + let maker_payment = send_nft_maker_payment(&setup, swap_amount.into()); log!( "Maker sent ERC1155 NFT payment, tx hash: {:02x}", maker_payment.tx_hash() ); wait_for_confirmations(&setup.maker_global_nft, &maker_payment, 100); - validate_nft_maker_payment(&setup, &maker_payment, amount.into()); + + validate_nft_maker_payment(&setup, &maker_payment, swap_amount.into()); let spend_tx = spend_nft_maker_payment(&setup, &maker_payment, &ContractType::Erc1155); log!( @@ -1047,9 +1053,13 @@ fn send_and_spend_erc1155_maker_payment() { ); wait_for_confirmations(&setup.taker_global_nft, &spend_tx, 100); + let taker_address = block_on(setup.taker_global_nft.my_addr()); - let balance = geth_erc1155_balance(taker_address, U256::from(token_id)); - assert_eq!(U256::from(amount), balance); + let taker_balance = geth_erc1155_balance(taker_address, U256::from(token_id)); + assert_eq!(U256::from(swap_amount), taker_balance); + + let maker_new_balance = geth_erc1155_balance(maker_address, U256::from(token_id)); + assert_eq!(U256::from(1u32), maker_new_balance); } #[test] @@ -1138,15 +1148,23 @@ fn send_and_refund_erc1155_maker_payment_timelock() { time_lock_to_refund, ); - let maker_payment_to_refund = send_nft_maker_payment(&setup, amount.into()); + let maker_address = block_on(setup.maker_global_nft.my_addr()); + let balance = geth_erc1155_balance(maker_address, U256::from(token_id)); + assert_eq!(U256::from(amount), balance); + + let swap_amount = 2u32; + let maker_payment_to_refund = send_nft_maker_payment(&setup, swap_amount.into()); log!( "Maker sent ERC1155 NFT payment, tx hash: {:02x}", maker_payment_to_refund.tx_hash() ); wait_for_confirmations(&setup.maker_global_nft, &maker_payment_to_refund, 150); - let balance = geth_erc1155_balance(geth_nft_maker_swap_v2(), U256::from(token_id)); - assert_eq!(U256::from(amount), balance); + + let swap_contract_balance = geth_erc1155_balance(geth_nft_maker_swap_v2(), U256::from(token_id)); + assert_eq!(U256::from(swap_amount), swap_contract_balance); + let balance = geth_erc1155_balance(maker_address, U256::from(token_id)); + assert_eq!(U256::from(1u32), balance); let refund_timelock_tx = refund_nft_maker_payment( &setup, @@ -1160,7 +1178,7 @@ fn send_and_refund_erc1155_maker_payment_timelock() { ); wait_for_confirmations(&setup.maker_global_nft, &refund_timelock_tx, 150); - let maker_address = block_on(setup.maker_global_nft.my_addr()); + let balance = geth_erc1155_balance(maker_address, U256::from(token_id)); assert_eq!(U256::from(amount), balance); } @@ -1213,7 +1231,6 @@ fn send_and_refund_erc1155_maker_payment_secret() { let token_id = 3u32; let amount = 3u32; let time_lock_to_refund = now_sec() + 1000; - let setup = setup_test( token_id, Some(amount), @@ -1223,15 +1240,23 @@ fn send_and_refund_erc1155_maker_payment_secret() { time_lock_to_refund, ); - let maker_payment_to_refund = send_nft_maker_payment(&setup, amount.into()); + let maker_address = block_on(setup.maker_global_nft.my_addr()); + let balance = geth_erc1155_balance(maker_address, U256::from(token_id)); + assert_eq!(U256::from(amount), balance); + + let swap_amount = 2u32; + let maker_payment_to_refund = send_nft_maker_payment(&setup, swap_amount.into()); log!( "Maker sent ERC1155 NFT payment, tx hash: {:02x}", maker_payment_to_refund.tx_hash() ); wait_for_confirmations(&setup.maker_global_nft, &maker_payment_to_refund, 100); - let balance = geth_erc1155_balance(geth_nft_maker_swap_v2(), U256::from(token_id)); - assert_eq!(U256::from(amount), balance); + + let swap_contract_balance = geth_erc1155_balance(geth_nft_maker_swap_v2(), U256::from(token_id)); + assert_eq!(U256::from(swap_amount), swap_contract_balance); + let balance = geth_erc1155_balance(maker_address, U256::from(token_id)); + assert_eq!(U256::from(1u32), balance); let refund_secret_tx = refund_nft_maker_payment( &setup, @@ -1245,7 +1270,7 @@ fn send_and_refund_erc1155_maker_payment_secret() { ); wait_for_confirmations(&setup.maker_global_nft, &refund_secret_tx, 100); - let maker_address = block_on(setup.maker_global_nft.my_addr()); + let balance = geth_erc1155_balance(maker_address, U256::from(token_id)); assert_eq!(U256::from(amount), balance); } From ff4d30642d15b5cc999cb397962f542526ba10af Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 26 Jun 2024 17:45:37 +0700 Subject: [PATCH 068/233] eth tpu v2: leave comms about preimages --- mm2src/coins/eth.rs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 40a05f02f4..4d74fcc31a 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7102,22 +7102,29 @@ impl TakerCoinSwapOpsV2 for EthCoin { todo!() } + /// Eth doesnt have preimages async fn gen_taker_funding_spend_preimage( &self, - _args: &GenTakerFundingSpendArgs<'_, Self>, + args: &GenTakerFundingSpendArgs<'_, Self>, _swap_unique_data: &[u8], ) -> GenPreimageResult { - todo!() + let result = TxPreimageWithSig { + preimage: args.funding_tx.clone(), + signature: args.funding_tx.signature(), + }; + Ok(result) } + /// Eth doesnt have preimages async fn validate_taker_funding_spend_preimage( &self, _gen_args: &GenTakerFundingSpendArgs<'_, Self>, _preimage: &TxPreimageWithSig, ) -> ValidateTakerFundingSpendPreimageResult { - todo!() + Ok(()) } + /// Generates and signs a preimage spending funding tx to the combined taker payment async fn sign_and_send_taker_funding_spend( &self, _preimage: &TxPreimageWithSig, @@ -7131,20 +7138,26 @@ impl TakerCoinSwapOpsV2 for EthCoin { todo!() } + /// Eth doesnt have preimages async fn gen_taker_payment_spend_preimage( &self, - _args: &GenTakerPaymentSpendArgs<'_, Self>, + args: &GenTakerPaymentSpendArgs<'_, Self>, _swap_unique_data: &[u8], ) -> GenPreimageResult { - todo!() + let result = TxPreimageWithSig { + preimage: args.taker_tx.clone(), + signature: args.taker_tx.signature(), + }; + Ok(result) } + /// Eth doesnt have preimages async fn validate_taker_payment_spend_preimage( &self, _gen_args: &GenTakerPaymentSpendArgs<'_, Self>, _preimage: &TxPreimageWithSig, ) -> ValidateTakerPaymentSpendPreimageResult { - todo!() + Ok(()) } async fn sign_and_broadcast_taker_payment_spend( @@ -7166,5 +7179,6 @@ impl TakerCoinSwapOpsV2 for EthCoin { todo!() } + // TODO still use HtlcPubKey or it would be better to move to Public from ethkey fn derive_htlc_pubkey_v2(&self, _swap_unique_data: &[u8]) -> Self::Pubkey { todo!() } } From 2ae0b04521acd3aa8e8114bc98f6609b378392dc Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 28 Jun 2024 10:29:50 +0700 Subject: [PATCH 069/233] eth tpu v2: use Public from ethereum_types in impl ParseCoinAssocTypes for EthCoin --- mm2src/coins/eth.rs | 46 +++++++++++++++++++---------- mm2src/coins/eth/nft_swap_v2/mod.rs | 14 ++++----- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 4d74fcc31a..31550bc9dd 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -76,7 +76,6 @@ use futures::future::{join, join_all, select_ok, try_join_all, Either, FutureExt use futures01::Future; use http::Uri; use instant::Instant; -use keys::Public as HtlcPubKey; use mm2_core::mm_ctx::{MmArc, MmWeak}; use mm2_event_stream::behaviour::{EventBehaviour, EventInitStatus}; use mm2_net::transport::{KomodefiProxyAuthValidation, ProxyAuthValidationGenerator}; @@ -6798,20 +6797,14 @@ impl ToBytes for SignedEthTx { } } -#[derive(Debug, Display)] +#[derive(Debug, Display, EnumFromStringify)] pub enum EthAssocTypesError { InvalidHexString(String), + #[from_stringify("DecoderError")] TxParseError(String), ParseSignatureError(String), - KeysError(keys::Error), -} - -impl From for EthAssocTypesError { - fn from(e: DecoderError) -> Self { EthAssocTypesError::TxParseError(e.to_string()) } -} - -impl From for EthAssocTypesError { - fn from(e: keys::Error) -> Self { EthAssocTypesError::KeysError(e) } + #[from_stringify("secp256k1::Error")] + ParsePublicKeyError(String), } #[derive(Debug, Display)] @@ -6829,7 +6822,7 @@ impl From for EthNftAssocTypesError { impl ParseCoinAssocTypes for EthCoin { type Address = Address; type AddressParseError = MmError; - type Pubkey = HtlcPubKey; + type Pubkey = Public; type PubkeyParseError = MmError; type Tx = SignedEthTx; type TxParseError = MmError; @@ -6855,7 +6848,8 @@ impl ParseCoinAssocTypes for EthCoin { } fn parse_pubkey(&self, pubkey: &[u8]) -> Result { - HtlcPubKey::from_slice(pubkey).map_to_mm(EthAssocTypesError::from) + let pubkey = PublicKey::from_slice(pubkey)?; + Ok(Public::from_slice(&pubkey.serialize_uncompressed()[1..65])) } fn parse_tx(&self, tx: &[u8]) -> Result { @@ -6890,6 +6884,10 @@ impl ToBytes for ContractType { fn to_bytes(&self) -> Vec { self.to_string().into_bytes() } } +impl ToBytes for Public { + fn to_bytes(&self) -> Vec { self.0.to_vec() } +} + impl ParseNftAssocTypes for EthCoin { type ContractAddress = Address; type TokenId = BigUint; @@ -7179,6 +7177,24 @@ impl TakerCoinSwapOpsV2 for EthCoin { todo!() } - // TODO still use HtlcPubKey or it would be better to move to Public from ethkey - fn derive_htlc_pubkey_v2(&self, _swap_unique_data: &[u8]) -> Self::Pubkey { todo!() } + #[inline(always)] + fn derive_htlc_pubkey_v2(&self, _swap_unique_data: &[u8]) -> Self::Pubkey { + match self.priv_key_policy { + EthPrivKeyPolicy::Iguana(ref key_pair) + | EthPrivKeyPolicy::HDWallet { + activated_key: ref key_pair, + .. + } => *key_pair.public(), + EthPrivKeyPolicy::Trezor => todo!(), + #[cfg(target_arch = "wasm32")] + EthPrivKeyPolicy::Metamask(ref metamask_policy) => { + // The metamask public key should be uncompressed + // Remove the first byte (0x04) from the uncompressed public key + let pubkey_bytes: [u8; 64] = metamask_policy.public_key_uncompressed[1..65] + .try_into() + .expect("slice with incorrect length"); + Public::from_slice(&pubkey_bytes) + }, + } + } } diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index a2a9032439..13e6a207e5 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -2,6 +2,7 @@ use crate::coin_errors::{ValidatePaymentError, ValidatePaymentResult}; use ethabi::{Contract, Token}; use ethcore_transaction::Action; use ethereum_types::{Address, U256}; +use ethkey::public_to_address; use futures::compat::Future01CompatExt; use mm2_err_handle::prelude::{MapToMmResult, MmError, MmResult}; use mm2_number::BigDecimal; @@ -14,8 +15,8 @@ mod structs; use structs::{ExpectedHtlcParams, PaymentType, ValidationParams}; use super::ContractType; -use crate::eth::{addr_from_raw_pubkey, decode_contract_call, gas_limit::ETH_MAX_TRADE_GAS, EthCoin, EthCoinType, - MakerPaymentStateV2, SignedEthTx, ERC1155_CONTRACT, ERC721_CONTRACT, NFT_MAKER_SWAP_V2}; +use crate::eth::{decode_contract_call, gas_limit::ETH_MAX_TRADE_GAS, EthCoin, EthCoinType, MakerPaymentStateV2, + SignedEthTx, ERC1155_CONTRACT, ERC721_CONTRACT, NFT_MAKER_SWAP_V2}; use crate::{ParseCoinAssocTypes, RefundNftMakerPaymentArgs, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, TransactionErr, ValidateNftMakerPaymentArgs}; @@ -66,8 +67,7 @@ impl EthCoin { .map_err(ValidatePaymentError::InternalError)?; let etomic_swap_contract = args.nft_swap_info.swap_contract_address; let token_address = args.nft_swap_info.token_address; - let maker_address = - addr_from_raw_pubkey(args.maker_pub).map_to_mm(ValidatePaymentError::InternalError)?; + let maker_address = public_to_address(args.maker_pub); let time_lock_u32 = args .time_lock .try_into() @@ -108,8 +108,7 @@ impl EthCoin { }; validate_decoded_data(&decoded, &validation_params)?; - let taker_address = - addr_from_raw_pubkey(args.taker_pub).map_to_mm(ValidatePaymentError::InternalError)?; + let taker_address = public_to_address(args.taker_pub); let htlc_params = ExpectedHtlcParams { swap_id, taker_address, @@ -283,8 +282,7 @@ impl EthCoin { } fn prepare_htlc_data(&self, args: &SendNftMakerPaymentArgs<'_, Self>) -> Result, PrepareTxDataError> { - let taker_address = - addr_from_raw_pubkey(args.taker_pub).map_err(|e| PrepareTxDataError::Internal(ERRL!("{}", e)))?; + let taker_address = public_to_address(args.taker_pub); let time_lock_u32 = args .time_lock .try_into() From 604d182af56e5573b2bebe022aa717ba9b093a36 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 28 Jun 2024 13:08:56 +0700 Subject: [PATCH 070/233] change sleep duration in send_and_spend_erc721_maker_payment --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index dca50e0042..ede5df5b73 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -983,7 +983,7 @@ fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option Date: Fri, 28 Jun 2024 13:32:31 +0700 Subject: [PATCH 071/233] change sleep duration in send_and_refund_erc721_maker_payment_timelock and send_and_spend_erc20_maker_payment_impl --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index ede5df5b73..b481cb5552 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -851,7 +851,7 @@ fn send_and_refund_erc20_maker_payment_priority_fee() { } fn send_and_spend_erc20_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { - thread::sleep(Duration::from_secs(1)); + thread::sleep(Duration::from_secs(7)); let maker_erc20_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); let taker_erc20_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); @@ -983,7 +983,7 @@ fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option Date: Fri, 28 Jun 2024 13:47:49 +0700 Subject: [PATCH 072/233] change sleep duration in send_and_refund_erc721_maker_payment_timelock --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index b481cb5552..066f67f194 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1094,7 +1094,7 @@ fn test_nonce_lock() { #[test] fn send_and_refund_erc721_maker_payment_timelock() { - thread::sleep(Duration::from_secs(31)); + thread::sleep(Duration::from_secs(45)); let token_id = 2u32; let time_lock_to_refund = now_sec() - 1000; let setup = setup_test( From 933d4b98144a619ce98c500bf1291bef666264dd Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 28 Jun 2024 14:02:36 +0700 Subject: [PATCH 073/233] change sleep duration in send_and_refund_erc1155_maker_payment_timelock --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 066f67f194..8ba2c73c46 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1135,7 +1135,7 @@ fn send_and_refund_erc721_maker_payment_timelock() { #[test] fn send_and_refund_erc1155_maker_payment_timelock() { - thread::sleep(Duration::from_secs(20)); + thread::sleep(Duration::from_secs(29)); let token_id = 2u32; let amount = 3u32; let time_lock_to_refund = now_sec() - 1000; From 1e906003a3ab70845ef91a6f33bab12bbaf59998 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 1 Jul 2024 15:08:14 +0700 Subject: [PATCH 074/233] eth tpu v2: add swap_v2_contracts Opt param in EthActivationV2Request, remove swap_v2_contracts from legacy "enable" RPC and add if ctx.use_trading_proto_v2() check in eth_coin_from_conf_and_request_v2 --- mm2src/coins/eth.rs | 30 ++--- mm2src/coins/eth/eth_swap_v2.rs | 7 +- mm2src/coins/eth/eth_tests.rs | 4 - mm2src/coins/eth/eth_wasm_tests.rs | 2 - mm2src/coins/eth/for_tests.rs | 4 +- mm2src/coins/eth/v2_activation.rs | 34 ++++-- .../tests/docker_tests/docker_tests_inner.rs | 33 +++--- .../tests/docker_tests/eth_docker_tests.rs | 110 +++++------------- .../tests/docker_tests/swap_watcher_tests.rs | 81 +++++++------ mm2src/mm2_main/tests/mm2_tests/eth_tests.rs | 2 - .../tests/mm2_tests/mm2_tests_inner.rs | 8 -- mm2src/mm2_test_helpers/src/for_tests.rs | 10 -- 12 files changed, 124 insertions(+), 201 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 2e308d3b3d..1e6b99cdb0 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -613,9 +613,7 @@ pub struct EthCoinImpl { derivation_method: Arc, sign_message_prefix: Option, swap_contract_address: Address, - maker_swap_v2_contract: Address, - taker_swap_v2_contract: Address, - nft_maker_swap_v2_contract: Option
, + swap_v2_contracts: Option, fallback_swap_contract: Option
, contract_supports_watchers: bool, web3_instances: AsyncMutex>, @@ -666,6 +664,13 @@ pub struct Erc20TokenInfo { pub decimals: u8, } +#[derive(Copy, Clone, Deserialize)] +pub struct SwapV2Contracts { + pub maker_swap_v2_contract: Address, + pub taker_swap_v2_contract: Address, + pub nft_maker_swap_v2_contract: Address, +} + #[derive(Deserialize, Serialize)] #[serde(tag = "format")] pub enum EthAddressFormat { @@ -6232,21 +6237,6 @@ pub async fn eth_coin_from_conf_and_request( if swap_contract_address == Address::default() { return ERR!("swap_contract_address can't be zero address"); } - let maker_swap_v2_contract: Address = try_s!(json::from_value(req["maker_swap_v2_contract"].clone())); - if maker_swap_v2_contract == Address::default() { - return ERR!("maker_swap_v2_contract can't be zero address"); - } - let taker_swap_v2_contract: Address = try_s!(json::from_value(req["taker_swap_v2_contract"].clone())); - if taker_swap_v2_contract == Address::default() { - return ERR!("taker_swap_v2_contract can't be zero address"); - } - let nft_maker_swap_v2_contract: Option
= - try_s!(json::from_value(req["nft_maker_swap_v2_contract"].clone())); - if let Some(nft_maker_swap_v2) = nft_maker_swap_v2_contract { - if nft_maker_swap_v2 == Address::default() { - return ERR!("nft_maker_swap_v2_contract can't be zero address"); - } - } let fallback_swap_contract: Option
= try_s!(json::from_value(req["fallback_swap_contract"].clone())); if let Some(fallback) = fallback_swap_contract { if fallback == Address::default() { @@ -6400,9 +6390,7 @@ pub async fn eth_coin_from_conf_and_request( coin_type, sign_message_prefix, swap_contract_address, - maker_swap_v2_contract, - taker_swap_v2_contract, - nft_maker_swap_v2_contract, + swap_v2_contracts: None, fallback_swap_contract, contract_supports_watchers, decimals, diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index d0a2a24b35..a39b2a6ca8 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -24,6 +24,11 @@ impl EthCoin { &self, args: SendTakerFundingArgs<'_>, ) -> Result { + let taker_swap_v2_contract = self + .swap_v2_contracts + .as_ref() + .map(|contracts| contracts.taker_swap_v2_contract) + .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; let dex_fee = try_tx_s!(wei_from_big_decimal(&args.dex_fee.fee_amount().into(), self.decimals)); let payment_amount = try_tx_s!(wei_from_big_decimal( @@ -49,7 +54,7 @@ impl EthCoin { let data = try_tx_s!(self.prepare_taker_eth_funding_data(&funding_args).await); self.sign_and_send_transaction( payment_amount, - Action::Call(self.taker_swap_v2_contract), + Action::Call(taker_swap_v2_contract), data, U256::from(gas_limit::ETH_PAYMENT), ) diff --git a/mm2src/coins/eth/eth_tests.rs b/mm2src/coins/eth/eth_tests.rs index e378d5cbc2..4d8b97c493 100644 --- a/mm2src/coins/eth/eth_tests.rs +++ b/mm2src/coins/eth/eth_tests.rs @@ -788,8 +788,6 @@ fn polygon_check_if_my_payment_sent() { "coin": "MATIC", "urls": ["https://polygon-mainnet.g.alchemy.com/v2/9YYl6iMLmXXLoflMPHnMTC4Dcm2L2tFH"], "swap_contract_address": "0x9130b257d37a52e52f21054c4da3450c72f595ce", - "maker_swap_v2_contract": "0x9130b257d37a52e52f21054c4da3450c72f595ce", - "taker_swap_v2_contract": "0x9130b257d37a52e52f21054c4da3450c72f595ce", }); let priv_key_policy = PrivKeyBuildPolicy::IguanaPrivKey(IguanaPrivKey::from([1; 32])); @@ -942,8 +940,6 @@ fn test_eth_validate_valid_and_invalid_pubkey() { "coin": "MATIC", "urls": ["https://polygon-mainnet.g.alchemy.com/v2/9YYl6iMLmXXLoflMPHnMTC4Dcm2L2tFH"], "swap_contract_address": "0x9130b257d37a52e52f21054c4da3450c72f595ce", - "maker_swap_v2_contract": "0x9130b257d37a52e52f21054c4da3450c72f595ce", - "taker_swap_v2_contract": "0x9130b257d37a52e52f21054c4da3450c72f595ce", }); let priv_key = [ diff --git a/mm2src/coins/eth/eth_wasm_tests.rs b/mm2src/coins/eth/eth_wasm_tests.rs index db6d2cce3f..287b3fb79a 100644 --- a/mm2src/coins/eth/eth_wasm_tests.rs +++ b/mm2src/coins/eth/eth_wasm_tests.rs @@ -41,8 +41,6 @@ async fn init_eth_coin_helper() -> Result<(MmArc, MmCoinEnum), String> { let req = json!({ "urls":ETH_SEPOLIA_NODES, "swap_contract_address":ETH_SEPOLIA_SWAP_CONTRACT, - "maker_swap_v2_contract":ETH_SEPOLIA_SWAP_CONTRACT, - "taker_swap_v2_contract":ETH_SEPOLIA_SWAP_CONTRACT, }); Ok((ctx.clone(), lp_coininit(&ctx, "ETH", &req).await?)) } diff --git a/mm2src/coins/eth/for_tests.rs b/mm2src/coins/eth/for_tests.rs index d54390ae3c..34a92378a5 100644 --- a/mm2src/coins/eth/for_tests.rs +++ b/mm2src/coins/eth/for_tests.rs @@ -58,9 +58,7 @@ pub(crate) fn eth_coin_from_keypair( priv_key_policy: key_pair.into(), derivation_method: Arc::new(DerivationMethod::SingleAddress(my_address)), swap_contract_address: Address::from_str(ETH_SEPOLIA_SWAP_CONTRACT).unwrap(), - maker_swap_v2_contract: Address::from_str(ETH_SEPOLIA_SWAP_CONTRACT).unwrap(), - taker_swap_v2_contract: Address::from_str(ETH_SEPOLIA_SWAP_CONTRACT).unwrap(), - nft_maker_swap_v2_contract: None, + swap_v2_contracts: None, fallback_swap_contract, contract_supports_watchers: false, ticker, diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 147f8e8a98..7dfc9734c0 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -175,9 +175,8 @@ pub struct EthActivationV2Request { #[serde(default)] pub rpc_mode: EthRpcMode, pub swap_contract_address: Address, - pub maker_swap_v2_contract: Address, - pub taker_swap_v2_contract: Address, - pub nft_maker_swap_v2_contract: Option
, + #[serde(default)] + pub swap_v2_contracts: Option, pub fallback_swap_contract: Option
, #[serde(default)] pub contract_supports_watchers: bool, @@ -443,9 +442,7 @@ impl EthCoin { coin_type, sign_message_prefix: self.sign_message_prefix.clone(), swap_contract_address: self.swap_contract_address, - maker_swap_v2_contract: self.maker_swap_v2_contract, - taker_swap_v2_contract: self.taker_swap_v2_contract, - nft_maker_swap_v2_contract: self.nft_maker_swap_v2_contract, + swap_v2_contracts: self.swap_v2_contracts, fallback_swap_contract: self.fallback_swap_contract, contract_supports_watchers: self.contract_supports_watchers, decimals, @@ -539,9 +536,7 @@ impl EthCoin { derivation_method: self.derivation_method.clone(), sign_message_prefix: self.sign_message_prefix.clone(), swap_contract_address: self.swap_contract_address, - maker_swap_v2_contract: self.maker_swap_v2_contract, - taker_swap_v2_contract: self.taker_swap_v2_contract, - nft_maker_swap_v2_contract: self.nft_maker_swap_v2_contract, + swap_v2_contracts: self.swap_v2_contracts, fallback_swap_contract: self.fallback_swap_contract, contract_supports_watchers: self.contract_supports_watchers, web3_instances: AsyncMutex::new(web3_instances), @@ -602,6 +597,23 @@ pub async fn eth_coin_from_conf_and_request_v2( .into()); } + if ctx.use_trading_proto_v2() { + let contracts = req.swap_v2_contracts.as_ref().ok_or_else(|| { + EthActivationV2Error::InvalidPayload( + "swap_v2_contracts must be provided when using trading protocol v2".to_string(), + ) + })?; + if contracts.maker_swap_v2_contract == Address::default() + || contracts.taker_swap_v2_contract == Address::default() + || contracts.nft_maker_swap_v2_contract == Address::default() + { + return Err(EthActivationV2Error::InvalidSwapContractAddr( + "All swap_v2_contracts addresses must be non-zero".to_string(), + ) + .into()); + } + } + if let Some(fallback) = req.fallback_swap_contract { if fallback == Address::default() { return Err(EthActivationV2Error::InvalidFallbackSwapContract( @@ -699,9 +711,7 @@ pub async fn eth_coin_from_conf_and_request_v2( coin_type, sign_message_prefix, swap_contract_address: req.swap_contract_address, - maker_swap_v2_contract: req.maker_swap_v2_contract, - taker_swap_v2_contract: req.taker_swap_v2_contract, - nft_maker_swap_v2_contract: req.nft_maker_swap_v2_contract, + swap_v2_contracts: req.swap_v2_contracts, fallback_swap_contract: req.fallback_swap_contract, contract_supports_watchers: req.contract_supports_watchers, decimals: ETH_DECIMALS, diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs index f4555264fa..330dec30de 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs @@ -1,7 +1,6 @@ use crate::docker_tests::docker_tests_common::{generate_utxo_coin_with_privkey, trade_base_rel, GETH_RPC_URL, MM_CTX}; use crate::docker_tests::eth_docker_tests::{erc20_coin_with_random_privkey, erc20_contract_checksum, - fill_eth_erc20_with_private_key, init_swap_contract_addresses, - swap_contract}; + fill_eth_erc20_with_private_key, swap_contract}; use crate::integration_tests_common::*; use crate::{fill_address, generate_utxo_coin_with_random_privkey, random_secp256k1_secret, rmd160_from_priv, utxo_coin_from_privkey}; @@ -3590,8 +3589,6 @@ async fn enable_eth_with_tokens( "ticker": platform_coin, "erc20_tokens_requests": erc20_tokens_requests, "swap_contract_address": swap_contract_address, - "maker_swap_v2_contract": swap_contract_address, - "taker_swap_v2_contract": swap_contract_address, "nodes": nodes, "tx_history": true, "get_balances": balance, @@ -3610,7 +3607,7 @@ async fn enable_eth_with_tokens( #[test] fn test_enable_eth_coin_with_token_then_disable() { - let coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let coin = erc20_coin_with_random_privkey(swap_contract()); let priv_key = coin.display_priv_key().unwrap(); let coins = json!([eth_dev_conf(), erc20_dev_conf(&erc20_contract_checksum())]); @@ -3669,7 +3666,7 @@ fn test_enable_eth_coin_with_token_then_disable() { #[test] fn test_enable_eth_coin_with_token_without_balance() { - let coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let coin = erc20_coin_with_random_privkey(swap_contract()); let priv_key = coin.display_priv_key().unwrap(); let coins = json!([eth_dev_conf(), erc20_dev_conf(&erc20_contract_checksum())]); @@ -3718,8 +3715,8 @@ fn test_enable_eth_coin_with_token_without_balance() { #[test] fn test_eth_swap_contract_addr_negotiation_same_fallback() { - let bob_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); - let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let bob_coin = erc20_coin_with_random_privkey(swap_contract()); + let alice_coin = erc20_coin_with_random_privkey(swap_contract()); let bob_priv_key = bob_coin.display_priv_key().unwrap(); let alice_priv_key = alice_coin.display_priv_key().unwrap(); @@ -3811,8 +3808,8 @@ fn test_eth_swap_contract_addr_negotiation_same_fallback() { #[test] fn test_eth_swap_negotiation_fails_maker_no_fallback() { - let bob_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); - let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let bob_coin = erc20_coin_with_random_privkey(swap_contract()); + let alice_coin = erc20_coin_with_random_privkey(swap_contract()); let bob_priv_key = bob_coin.display_priv_key().unwrap(); let alice_priv_key = alice_coin.display_priv_key().unwrap(); @@ -4376,7 +4373,7 @@ fn test_gtc_taker_order_should_transform_to_maker() { #[test] fn test_set_price_must_save_order_to_db() { - let private_key_str = erc20_coin_with_random_privkey(init_swap_contract_addresses()) + let private_key_str = erc20_coin_with_random_privkey(swap_contract()) .display_priv_key() .unwrap(); let coins = json!([eth_dev_conf(), erc20_dev_conf(&erc20_contract_checksum())]); @@ -4537,7 +4534,7 @@ fn test_sell_response_format() { #[test] fn test_set_price_conf_settings() { - let private_key_str = erc20_coin_with_random_privkey(init_swap_contract_addresses()) + let private_key_str = erc20_coin_with_random_privkey(swap_contract()) .display_priv_key() .unwrap(); @@ -4610,7 +4607,7 @@ fn test_set_price_conf_settings() { #[test] fn test_buy_conf_settings() { - let private_key_str = erc20_coin_with_random_privkey(init_swap_contract_addresses()) + let private_key_str = erc20_coin_with_random_privkey(swap_contract()) .display_priv_key() .unwrap(); @@ -4683,7 +4680,7 @@ fn test_buy_conf_settings() { #[test] fn test_sell_conf_settings() { - let private_key_str = erc20_coin_with_random_privkey(init_swap_contract_addresses()) + let private_key_str = erc20_coin_with_random_privkey(swap_contract()) .display_priv_key() .unwrap(); @@ -4817,8 +4814,8 @@ fn test_my_orders_response_format() { #[test] fn test_my_orders_after_matched() { - let bob_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); - let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let bob_coin = erc20_coin_with_random_privkey(swap_contract()); + let alice_coin = erc20_coin_with_random_privkey(swap_contract()); let coins = json!([eth_dev_conf(), erc20_dev_conf(&erc20_contract_checksum())]); @@ -4913,8 +4910,8 @@ fn test_my_orders_after_matched() { #[test] fn test_update_maker_order_after_matched() { - let bob_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); - let alice_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let bob_coin = erc20_coin_with_random_privkey(swap_contract()); + let alice_coin = erc20_coin_with_random_privkey(swap_contract()); let coins = json!([eth_dev_conf(), erc20_dev_conf(&erc20_contract_checksum())]); diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 8ba2c73c46..87595ed9bd 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -45,11 +45,13 @@ pub fn geth_account() -> Address { unsafe { GETH_ACCOUNT } } /// GETH_SWAP_CONTRACT is set once during initialization before tests start pub fn swap_contract() -> Address { unsafe { GETH_SWAP_CONTRACT } } +#[allow(dead_code)] /// # Safety /// /// GETH_MAKER_SWAP_V2 is set once during initialization before tests start pub fn maker_swap_v2() -> Address { unsafe { GETH_MAKER_SWAP_V2 } } +#[allow(dead_code)] /// # Safety /// /// GETH_TAKER_SWAP_V2 is set once during initialization before tests start @@ -275,14 +277,12 @@ pub(crate) async fn fill_erc721_info(eth_coin: &EthCoin, token_address: Address, } /// Creates ETH protocol coin supplied with 100 ETH -pub fn eth_coin_with_random_privkey_using_urls(swap_addresses: SwapAddressesWrapper, urls: &[&str]) -> EthCoin { +pub fn eth_coin_with_random_privkey_using_urls(swap_contract_address: Address, urls: &[&str]) -> EthCoin { let eth_conf = eth_dev_conf(); let req = json!({ "method": "enable", "coin": "ETH", - "swap_contract_address": swap_addresses.swap_contract_address, - "maker_swap_v2_contract": swap_addresses.maker_swap_v2_contract, - "taker_swap_v2_contract": swap_addresses.taker_swap_v2_contract, + "swap_contract_address": swap_contract_address, "urls": urls, }); @@ -308,46 +308,18 @@ pub fn eth_coin_with_random_privkey_using_urls(swap_addresses: SwapAddressesWrap eth_coin } -#[derive(Clone, Debug)] -pub struct SwapAddressesWrapper { - pub swap_contract_address: Address, - pub maker_swap_v2_contract: Address, - pub taker_swap_v2_contract: Address, - pub nft_maker_swap_v2_contract: Address, -} - -pub fn init_swap_contract_addresses() -> SwapAddressesWrapper { - SwapAddressesWrapper { - swap_contract_address: swap_contract(), - maker_swap_v2_contract: maker_swap_v2(), - taker_swap_v2_contract: taker_swap_v2(), - nft_maker_swap_v2_contract: geth_nft_maker_swap_v2(), - } -} - -pub fn init_watchers_swap_contract() -> SwapAddressesWrapper { - SwapAddressesWrapper { - swap_contract_address: watchers_swap_contract(), - maker_swap_v2_contract: maker_swap_v2(), - taker_swap_v2_contract: taker_swap_v2(), - nft_maker_swap_v2_contract: geth_nft_maker_swap_v2(), - } -} - /// Creates ETH protocol coin supplied with 100 ETH, using the default GETH_RPC_URL -pub fn eth_coin_with_random_privkey(swap_addresses: SwapAddressesWrapper) -> EthCoin { - eth_coin_with_random_privkey_using_urls(swap_addresses, &[GETH_RPC_URL]) +pub fn eth_coin_with_random_privkey(swap_contract_address: Address) -> EthCoin { + eth_coin_with_random_privkey_using_urls(swap_contract_address, &[GETH_RPC_URL]) } /// Creates ERC20 protocol coin supplied with 1 ETH and 100 token -pub fn erc20_coin_with_random_privkey(swap_addresses: SwapAddressesWrapper) -> EthCoin { +pub fn erc20_coin_with_random_privkey(swap_contract_address: Address) -> EthCoin { let erc20_conf = erc20_dev_conf(&erc20_contract_checksum()); let req = json!({ "method": "enable", "coin": "ERC20DEV", - "swap_contract_address": swap_addresses.swap_contract_address, - "maker_swap_v2_contract": swap_addresses.maker_swap_v2_contract, - "taker_swap_v2_contract": swap_addresses.taker_swap_v2_contract, + "swap_contract_address": swap_contract_address, "urls": [GETH_RPC_URL], }); @@ -386,16 +358,13 @@ pub enum TestNftType { /// Generates a global NFT coin instance with a random private key and an initial 100 ETH balance. /// Optionally mints a specified NFT (either ERC721 or ERC1155) to the global NFT address, /// with details recorded in the `nfts_infos` field based on the provided `nft_type`. -pub fn global_nft_with_random_privkey(swap_addresses: SwapAddressesWrapper, nft_type: Option) -> EthCoin { +pub fn global_nft_with_random_privkey(swap_contract_address: Address, nft_type: Option) -> EthCoin { let nft_conf = nft_dev_conf(); let req = json!({ "method": "enable", "coin": "NFT_ETH", "urls": [GETH_RPC_URL], - "swap_contract_address": swap_addresses.swap_contract_address, - "maker_swap_v2_contract": swap_addresses.maker_swap_v2_contract, - "taker_swap_v2_contract": swap_addresses.taker_swap_v2_contract, - "nft_maker_swap_v2_contract": swap_addresses.nft_maker_swap_v2_contract, + "swap_contract_address": swap_contract_address, }); let global_nft = block_on(eth_coin_from_conf_and_request( @@ -438,7 +407,7 @@ pub fn global_nft_with_random_privkey(swap_addresses: SwapAddressesWrapper, nft_ /// Can be used to generate global NFT from Sepolia Maker/Taker priv keys. fn global_nft_from_privkey( ctx: &MmArc, - swap_addresses: SwapAddressesWrapper, + swap_contract_address: Address, secret: &'static str, nft_type: Option, ) -> EthCoin { @@ -447,10 +416,7 @@ fn global_nft_from_privkey( "method": "enable", "coin": "NFT_ETH", "urls": [SEPOLIA_RPC_URL], - "swap_contract_address": swap_addresses.swap_contract_address, - "maker_swap_v2_contract": swap_addresses.maker_swap_v2_contract, - "taker_swap_v2_contract": swap_addresses.taker_swap_v2_contract, - "nft_maker_swap_v2_contract": swap_addresses.nft_maker_swap_v2_contract, + "swap_contract_address": swap_contract_address, }); let priv_key = Secp256k1Secret::from(secret); @@ -550,8 +516,6 @@ pub fn fill_eth_erc20_with_private_key(priv_key: Secp256k1Secret) { "coin": "ETH", "urls": [GETH_RPC_URL], "swap_contract_address": swap_contract(), - "maker_swap_v2_contract": maker_swap_v2(), - "taker_swap_v2_contract": taker_swap_v2(), }); let eth_coin = block_on(eth_coin_from_conf_and_request( @@ -574,8 +538,6 @@ pub fn fill_eth_erc20_with_private_key(priv_key: Secp256k1Secret) { "coin": "ERC20DEV", "urls": [GETH_RPC_URL], "swap_contract_address": swap_contract(), - "maker_swap_v2_contract": maker_swap_v2(), - "taker_swap_v2_contract": taker_swap_v2(), }); let _erc20_coin = block_on(eth_coin_from_conf_and_request( @@ -597,7 +559,7 @@ pub fn fill_eth_erc20_with_private_key(priv_key: Secp256k1Secret) { fn send_and_refund_eth_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { thread::sleep(Duration::from_secs(3)); - let eth_coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let eth_coin = eth_coin_with_random_privkey(swap_contract()); eth_coin.set_swap_transaction_fee_policy(swap_txfee_policy); let time_lock = now_sec() - 100; @@ -679,9 +641,8 @@ fn send_and_refund_eth_maker_payment_internal_gas_policy() { fn send_and_refund_eth_maker_payment_priority_fee() { send_and_refund_eth_maker_payment_impl(SwapTxFeePolicy::Medium); } fn send_and_spend_eth_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { - let swap_addresses = init_swap_contract_addresses(); - let maker_eth_coin = eth_coin_with_random_privkey(swap_addresses.clone()); - let taker_eth_coin = eth_coin_with_random_privkey(swap_addresses); + let maker_eth_coin = eth_coin_with_random_privkey(swap_contract()); + let taker_eth_coin = eth_coin_with_random_privkey(swap_contract()); maker_eth_coin.set_swap_transaction_fee_policy(swap_txfee_policy.clone()); taker_eth_coin.set_swap_transaction_fee_policy(swap_txfee_policy); @@ -766,7 +727,7 @@ fn send_and_spend_eth_maker_payment_priority_fee() { send_and_spend_eth_maker_pa fn send_and_refund_erc20_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { thread::sleep(Duration::from_secs(10)); - let erc20_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let erc20_coin = erc20_coin_with_random_privkey(swap_contract()); erc20_coin.set_swap_transaction_fee_policy(swap_txfee_policy); let time_lock = now_sec() - 100; @@ -852,8 +813,8 @@ fn send_and_refund_erc20_maker_payment_priority_fee() { fn send_and_spend_erc20_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { thread::sleep(Duration::from_secs(7)); - let maker_erc20_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); - let taker_erc20_coin = erc20_coin_with_random_privkey(init_swap_contract_addresses()); + let maker_erc20_coin = erc20_coin_with_random_privkey(swap_contract()); + let taker_erc20_coin = erc20_coin_with_random_privkey(swap_contract()); maker_erc20_coin.set_swap_transaction_fee_policy(swap_txfee_policy.clone()); taker_erc20_coin.set_swap_transaction_fee_policy(swap_txfee_policy); @@ -965,15 +926,7 @@ fn wait_pending_transactions(wallet_address: Address) { #[allow(dead_code)] fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option) -> EthCoin { match block_on(lp_coinfind(ctx, NFT_ETH)).unwrap() { - None => { - let swap_addresses = SwapAddressesWrapper { - swap_contract_address: swap_contract(), - maker_swap_v2_contract: maker_swap_v2(), - taker_swap_v2_contract: taker_swap_v2(), - nft_maker_swap_v2_contract: sepolia_etomic_maker_nft(), - }; - global_nft_from_privkey(ctx, swap_addresses, priv_key, nft_type) - }, + None => global_nft_from_privkey(ctx, sepolia_etomic_maker_nft(), priv_key, nft_type), Some(mm_coin) => match mm_coin { MmCoinEnum::EthCoin(nft) => nft, _ => panic!("Unexpected coin type found. Expected MmCoinEnum::EthCoin"), @@ -990,7 +943,7 @@ fn send_and_spend_erc721_maker_payment() { token_id, None, ContractType::Erc721, - init_swap_contract_addresses(), + geth_nft_maker_swap_v2(), geth_erc721_contract(), time_lock, ); @@ -1026,7 +979,7 @@ fn send_and_spend_erc1155_maker_payment() { token_id, Some(amount), ContractType::Erc1155, - init_swap_contract_addresses(), + geth_nft_maker_swap_v2(), geth_erc1155_contract(), time_lock, ); @@ -1065,8 +1018,7 @@ fn send_and_spend_erc1155_maker_payment() { #[test] fn test_nonce_several_urls() { // Use one working and one failing URL. - let coin = - eth_coin_with_random_privkey_using_urls(init_swap_contract_addresses(), &[GETH_RPC_URL, "http://127.0.0.1:0"]); + let coin = eth_coin_with_random_privkey_using_urls(swap_contract(), &[GETH_RPC_URL, "http://127.0.0.1:0"]); let my_address = block_on(coin.derivation_method().single_addr_or_err()).unwrap(); let (old_nonce, _) = coin.clone().get_addr_nonce(my_address).wait().unwrap(); @@ -1081,7 +1033,7 @@ fn test_nonce_several_urls() { fn test_nonce_lock() { use futures::future::join_all; - let coin = eth_coin_with_random_privkey(init_swap_contract_addresses()); + let coin = eth_coin_with_random_privkey(swap_contract()); let my_address = block_on(coin.derivation_method().single_addr_or_err()).unwrap(); let futures = (0..5).map(|_| coin.send_to_address(my_address, 200000000.into()).compat()); let results = block_on(join_all(futures)); @@ -1101,7 +1053,7 @@ fn send_and_refund_erc721_maker_payment_timelock() { token_id, None, ContractType::Erc721, - init_swap_contract_addresses(), + geth_nft_maker_swap_v2(), geth_erc721_contract(), time_lock_to_refund, ); @@ -1143,7 +1095,7 @@ fn send_and_refund_erc1155_maker_payment_timelock() { token_id, Some(amount), ContractType::Erc1155, - init_swap_contract_addresses(), + geth_nft_maker_swap_v2(), geth_erc1155_contract(), time_lock_to_refund, ); @@ -1193,7 +1145,7 @@ fn send_and_refund_erc721_maker_payment_secret() { token_id, None, ContractType::Erc721, - init_swap_contract_addresses(), + geth_nft_maker_swap_v2(), geth_erc721_contract(), time_lock_to_refund, ); @@ -1235,7 +1187,7 @@ fn send_and_refund_erc1155_maker_payment_secret() { token_id, Some(amount), ContractType::Erc1155, - init_swap_contract_addresses(), + geth_nft_maker_swap_v2(), geth_erc1155_contract(), time_lock_to_refund, ); @@ -1302,7 +1254,7 @@ fn setup_test( token_id: u32, amount: Option, contract_type: ContractType, - swap_addresses: SwapAddressesWrapper, + swap_contract_address: Address, token_contract: Address, time_lock: u64, ) -> NftTestSetup { @@ -1314,8 +1266,8 @@ fn setup_test( }, }; - let maker_global_nft = global_nft_with_random_privkey(swap_addresses.clone(), Some(nft_type)); - let taker_global_nft = global_nft_with_random_privkey(swap_addresses.clone(), None); + let maker_global_nft = global_nft_with_random_privkey(swap_contract_address, Some(nft_type)); + let taker_global_nft = global_nft_with_random_privkey(swap_contract_address, None); let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); let taker_secret = vec![0; 32]; @@ -1327,7 +1279,7 @@ fn setup_test( token_address: token_contract, token_id, contract_type, - swap_contract_address: swap_addresses.nft_maker_swap_v2_contract, + swap_contract_address, }; NftTestSetup { diff --git a/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs b/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs index 3b43136cf6..98973aaf96 100644 --- a/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs @@ -1,7 +1,6 @@ use crate::docker_tests::docker_tests_common::GETH_RPC_URL; use crate::docker_tests::eth_docker_tests::{erc20_coin_with_random_privkey, erc20_contract_checksum, - eth_coin_with_random_privkey, init_watchers_swap_contract, - watchers_swap_contract}; + eth_coin_with_random_privkey, watchers_swap_contract}; use crate::integration_tests_common::*; use crate::{generate_utxo_coin_with_privkey, generate_utxo_coin_with_random_privkey, random_secp256k1_secret}; use coins::coin_errors::ValidatePaymentError; @@ -764,9 +763,9 @@ fn test_watcher_spends_maker_payment_utxo_utxo() { #[test] fn test_watcher_spends_maker_payment_utxo_eth() { - let alice_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); - let bob_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let alice_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let bob_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); let balances = start_swaps_and_get_balances( "ETH", @@ -793,9 +792,9 @@ fn test_watcher_spends_maker_payment_utxo_eth() { #[test] fn test_watcher_spends_maker_payment_eth_utxo() { - let alice_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); - let bob_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let alice_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let bob_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); let balances = start_swaps_and_get_balances( "MYCOIN", @@ -835,9 +834,9 @@ fn test_watcher_spends_maker_payment_eth_utxo() { #[test] fn test_watcher_spends_maker_payment_eth_erc20() { - let alice_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); - let bob_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let alice_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); + let bob_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); let balances = start_swaps_and_get_balances( "ERC20DEV", @@ -868,9 +867,9 @@ fn test_watcher_spends_maker_payment_eth_erc20() { #[test] fn test_watcher_spends_maker_payment_erc20_eth() { - let alice_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); - let bob_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let alice_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let bob_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); let balances = start_swaps_and_get_balances( "ETH", @@ -898,9 +897,9 @@ fn test_watcher_spends_maker_payment_erc20_eth() { #[test] fn test_watcher_spends_maker_payment_utxo_erc20() { - let alice_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); - let bob_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let alice_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); + let bob_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); let balances = start_swaps_and_get_balances( "ERC20DEV", @@ -931,9 +930,9 @@ fn test_watcher_spends_maker_payment_utxo_erc20() { #[test] fn test_watcher_spends_maker_payment_erc20_utxo() { - let alice_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); - let bob_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let alice_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let bob_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); let balances = start_swaps_and_get_balances( "MYCOIN", @@ -1010,9 +1009,9 @@ fn test_watcher_refunds_taker_payment_utxo() { #[test] fn test_watcher_refunds_taker_payment_eth() { - let alice_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); - let bob_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let alice_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let bob_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); let balances = start_swaps_and_get_balances( "ETH", @@ -1033,9 +1032,9 @@ fn test_watcher_refunds_taker_payment_eth() { #[test] fn test_watcher_refunds_taker_payment_erc20() { - let alice_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); - let bob_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let alice_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); + let bob_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); let balances = start_swaps_and_get_balances( "ERC20DEV", @@ -1088,9 +1087,9 @@ fn test_watcher_waits_for_taker_utxo() { #[test] fn test_watcher_waits_for_taker_eth() { - let alice_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); - let bob_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); - let watcher_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let alice_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); + let bob_coin = eth_coin_with_random_privkey(watchers_swap_contract()); + let watcher_coin = eth_coin_with_random_privkey(watchers_swap_contract()); start_swaps_and_get_balances( "ERC20DEV", @@ -1329,7 +1328,7 @@ fn test_watcher_validate_taker_fee_eth() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run let lock_duration = get_payment_locktime(); - let taker_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let taker_coin = eth_coin_with_random_privkey(watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pubkey = taker_keypair.public(); @@ -1436,7 +1435,7 @@ fn test_watcher_validate_taker_fee_erc20() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run let lock_duration = get_payment_locktime(); - let taker_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); + let taker_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pubkey = taker_keypair.public(); @@ -1753,7 +1752,7 @@ fn test_watcher_validate_taker_payment_utxo() { fn test_watcher_validate_taker_payment_eth() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let taker_coin = eth_coin_with_random_privkey(watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); @@ -1996,7 +1995,7 @@ fn test_watcher_validate_taker_payment_eth() { fn test_watcher_validate_taker_payment_erc20() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); + let taker_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); @@ -2324,11 +2323,11 @@ fn test_taker_validates_taker_payment_refund_utxo() { fn test_taker_validates_taker_payment_refund_eth() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let taker_coin = eth_coin_with_random_privkey(watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); - let maker_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let maker_coin = eth_coin_with_random_privkey(watchers_swap_contract()); let maker_keypair = maker_coin.derive_htlc_key_pair(&[]); let maker_pub = maker_keypair.public(); @@ -2645,7 +2644,7 @@ fn test_taker_validates_taker_payment_refund_eth() { fn test_taker_validates_taker_payment_refund_erc20() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); + let taker_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); @@ -2854,11 +2853,11 @@ fn test_taker_validates_maker_payment_spend_utxo() { fn test_taker_validates_maker_payment_spend_eth() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let taker_coin = eth_coin_with_random_privkey(watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); - let maker_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let maker_coin = eth_coin_with_random_privkey(watchers_swap_contract()); let maker_keypair = maker_coin.derive_htlc_key_pair(&[]); let maker_pub = maker_keypair.public(); @@ -3184,11 +3183,11 @@ fn test_taker_validates_maker_payment_spend_eth() { fn test_taker_validates_maker_payment_spend_erc20() { let timeout = wait_until_sec(120); // timeout if test takes more than 120 seconds to run - let taker_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); + let taker_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); let taker_keypair = taker_coin.derive_htlc_key_pair(&[]); let taker_pub = taker_keypair.public(); - let maker_coin = erc20_coin_with_random_privkey(init_watchers_swap_contract()); + let maker_coin = erc20_coin_with_random_privkey(watchers_swap_contract()); let maker_keypair = maker_coin.derive_htlc_key_pair(&[]); let maker_pub = maker_keypair.public(); @@ -3390,7 +3389,7 @@ fn test_send_taker_payment_refund_preimage_utxo() { fn test_watcher_reward() { let timeout = wait_until_sec(300); // timeout if test takes more than 300 seconds to run let (_ctx, utxo_coin, _) = generate_utxo_coin_with_random_privkey("MYCOIN", 1000u64.into()); - let eth_coin = eth_coin_with_random_privkey(init_watchers_swap_contract()); + let eth_coin = eth_coin_with_random_privkey(watchers_swap_contract()); let watcher_reward = block_on(eth_coin.get_taker_watcher_reward(&MmCoinEnum::EthCoin(eth_coin.clone()), None, None, None, timeout)) diff --git a/mm2src/mm2_main/tests/mm2_tests/eth_tests.rs b/mm2src/mm2_main/tests/mm2_tests/eth_tests.rs index ab754a8c4f..fc904a368f 100644 --- a/mm2src/mm2_main/tests/mm2_tests/eth_tests.rs +++ b/mm2src/mm2_main/tests/mm2_tests/eth_tests.rs @@ -68,8 +68,6 @@ async fn enable_eth(mm: &MarketMakerIt, platform_coin: &str, nodes: &[&str]) -> "coin": platform_coin, "urls": nodes, "swap_contract_address": ETH_SEPOLIA_SWAP_CONTRACT, - "maker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, - "taker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, "mm2": 1, })) .await diff --git a/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs b/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs index 5fc6622e89..06abd46a92 100644 --- a/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs +++ b/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs @@ -3573,8 +3573,6 @@ fn test_get_raw_transaction() { "urls": &[ETH_MAINNET_NODE], // Dev chain swap contract address "swap_contract_address": ETH_MAINNET_SWAP_CONTRACT, - "maker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, - "taker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, "mm2": 1, }))) .unwrap(); @@ -6034,8 +6032,6 @@ mod trezor_tests { "coin": "ETH", "urls": ETH_SEPOLIA_NODES, "swap_contract_address": ETH_SEPOLIA_SWAP_CONTRACT, - "maker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, - "taker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, "priv_key_policy": "Trezor", }); @@ -6284,8 +6280,6 @@ mod trezor_tests { {"url": "https://rpc.sepolia.org/"} ], "swap_contract_address": ETH_SEPOLIA_SWAP_CONTRACT, - "maker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, - "taker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, "erc20_tokens_requests": [{"ticker": ticker_token}], "priv_key_policy": "Trezor" })) @@ -6404,8 +6398,6 @@ mod trezor_tests { {"url": ETH_SEPOLIA_NODES[0]} ], "swap_contract_address": ETH_SEPOLIA_SWAP_CONTRACT, - "maker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, - "taker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, "erc20_tokens_requests": [], "priv_key_policy": "Trezor" })) diff --git a/mm2src/mm2_test_helpers/src/for_tests.rs b/mm2src/mm2_test_helpers/src/for_tests.rs index 0212cf5c46..1105fa92e1 100644 --- a/mm2src/mm2_test_helpers/src/for_tests.rs +++ b/mm2src/mm2_test_helpers/src/for_tests.rs @@ -1832,8 +1832,6 @@ pub async fn enable_qrc20( "servers": servers, "mm2": 1, "swap_contract_address": swap_contract_address, - "maker_swap_v2_contract": swap_contract_address, - "taker_swap_v2_contract": swap_contract_address, "path_to_address": path_to_address.unwrap_or_default(), })) .await @@ -1920,8 +1918,6 @@ pub async fn enable_native( "urls": urls, // Dev chain swap contract address "swap_contract_address": ETH_SEPOLIA_SWAP_CONTRACT, - "maker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, - "taker_swap_v2_contract": ETH_SEPOLIA_SWAP_CONTRACT, "path_to_address": path_to_address.unwrap_or_default(), "mm2": 1, })) @@ -1946,8 +1942,6 @@ pub async fn enable_eth_coin( "coin": coin, "urls": urls, "swap_contract_address": swap_contract_address, - "maker_swap_v2_contract": swap_contract_address, - "taker_swap_v2_contract": swap_contract_address, "fallback_swap_contract": fallback_swap_contract, "mm2": 1, "contract_supports_watchers": contract_supports_watcher @@ -3141,8 +3135,6 @@ pub async fn init_eth_with_tokens( "params": { "ticker": platform_coin, "swap_contract_address": swap_contract_address, - "maker_swap_v2_contract": swap_contract_address, - "taker_swap_v2_contract": swap_contract_address, "nodes": nodes, "tx_history": true, "erc20_tokens_requests": erc20_tokens_requests, @@ -3379,8 +3371,6 @@ pub async fn test_qrc20_history_impl(local_start: Option) { "mm2": 1, "tx_history": true, "swap_contract_address": "0xd362e096e873eb7907e205fadc6175c6fec7bc44", - "maker_swap_v2_contract": "0xd362e096e873eb7907e205fadc6175c6fec7bc44", - "taker_swap_v2_contract": "0xd362e096e873eb7907e205fadc6175c6fec7bc44", })) .await .unwrap(); From b9049bfea5ec07cf48d95245236c16e9364b079f Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 3 Jul 2024 14:53:05 +0700 Subject: [PATCH 075/233] state machine: change doc comment related to sign_and_send_taker_funding_spend --- mm2src/coins/eth.rs | 2 +- mm2src/coins/lp_coins.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 1e6b99cdb0..86c9aab0ea 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7095,7 +7095,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { Ok(()) } - /// Generates and signs a preimage spending funding tx to the combined taker payment + /// Eth doesnt use multisig async fn sign_and_send_taker_funding_spend( &self, _preimage: &TxPreimageWithSig, diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 64de5011a4..5fe10482d0 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1879,7 +1879,7 @@ pub trait TakerCoinSwapOpsV2: ParseCoinAssocTypes + Send + Sync + 'static { preimage: &TxPreimageWithSig, ) -> ValidateTakerFundingSpendPreimageResult; - /// Generates and signs a preimage spending funding tx to the combined taker payment + /// Sign and send a spending funding tx to the combined taker payment async fn sign_and_send_taker_funding_spend( &self, preimage: &TxPreimageWithSig, From 8e4cd71f6d44309485f5dbcb07efa4f438b89d0e Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 3 Jul 2024 17:16:06 +0700 Subject: [PATCH 076/233] eth tpu v2: send_taker_funding Erc20 WIP (need to optimize code) --- mm2src/coins/eth/eth_swap_v2.rs | 72 +++++++++++++++++-- mm2src/coins/lp_coins.rs | 2 + mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 2 + .../tests/docker_tests/swap_proto_v2_tests.rs | 5 ++ 4 files changed, 76 insertions(+), 5 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index a39b2a6ca8..4fa8b8154b 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,6 +1,6 @@ -use crate::eth::{addr_from_raw_pubkey, gas_limit, wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, +use super::eth::{addr_from_raw_pubkey, gas_limit, wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; -use crate::{SendTakerFundingArgs, TransactionErr}; +use super::{SendTakerFundingArgs, Transaction, TransactionErr}; use enum_derives::EnumFromStringify; use ethabi::Token; use ethcore_transaction::Action; @@ -8,7 +8,6 @@ use ethereum_types::{Address, U256}; use futures::compat::Future01CompatExt; use std::convert::TryInto; -#[allow(dead_code)] struct TakerFundingArgs<'a> { dex_fee: U256, payment_amount: U256, @@ -61,8 +60,50 @@ impl EthCoin { .compat() .await }, - EthCoinType::Erc20 { .. } => { - todo!() + EthCoinType::Erc20 { + platform: _, + token_addr, + } => { + let allowed = self + .allowance(taker_swap_v2_contract) + .compat() + .await + .map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?; + let data = try_tx_s!(self.prepare_taker_erc20_funding_data(&funding_args, *token_addr).await); + if allowed < payment_amount { + let approved_tx = self.approve(taker_swap_v2_contract, U256::max_value()).compat().await?; + self.wait_for_required_allowance( + taker_swap_v2_contract, + payment_amount, + args.wait_for_confirmation_until, + ) + .compat() + .await + .map_err(|e| { + TransactionErr::Plain(ERRL!( + "Allowed value was not updated in time after sending approve transaction {:02x}: {}", + approved_tx.tx_hash_as_bytes(), + e + )) + })?; + self.sign_and_send_transaction( + U256::from(0), + Action::Call(taker_swap_v2_contract), + data, + U256::from(gas_limit::ERC20_PAYMENT), + ) + .compat() + .await + } else { + self.sign_and_send_transaction( + U256::from(0), + Action::Call(taker_swap_v2_contract), + data, + U256::from(gas_limit::ERC20_PAYMENT), + ) + .compat() + .await + } }, EthCoinType::Nft { .. } => Err(TransactionErr::ProtocolNotSupported( "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), @@ -84,6 +125,27 @@ impl EthCoin { ])?; Ok(data) } + + async fn prepare_taker_erc20_funding_data( + &self, + args: &TakerFundingArgs<'_>, + token_addr: Address, + ) -> Result, PrepareTxDataError> { + let function = TAKER_SWAP_V2.function("erc20TakerPayment")?; + let id = self.etomic_swap_v2_id(args.funding_time_lock, args.payment_time_lock, args.taker_secret_hash); + let data = function.encode_input(&[ + Token::FixedBytes(id), + Token::Uint(args.payment_amount), + Token::Uint(args.dex_fee), + Token::Address(token_addr), + Token::Address(args.maker_address), + Token::FixedBytes(args.taker_secret_hash.to_vec()), + Token::FixedBytes(args.maker_secret_hash.to_vec()), + Token::Uint(args.funding_time_lock.into()), + Token::Uint(args.payment_time_lock.into()), + ])?; + Ok(data) + } } #[allow(dead_code)] diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 5fe10482d0..7d7bf1dac8 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1297,6 +1297,8 @@ pub struct SendTakerFundingArgs<'a> { pub trading_amount: BigDecimal, /// Unique data of specific swap pub swap_unique_data: &'a [u8], + /// As of now, this field is specifically used to wait for confirmations of ERC20 approval transaction. + pub wait_for_confirmation_until: u64, } /// Helper struct wrapping arguments for [TakerCoinSwapOpsV2::refund_taker_funding_secret] diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs index 83b67cf57f..ac5edf9312 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs @@ -1230,6 +1230,8 @@ impl Date: Wed, 3 Jul 2024 21:37:01 +0700 Subject: [PATCH 077/233] change sleep duration in send_and_refund_erc721_maker_payment_timelock --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 87595ed9bd..38b2075c13 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1046,7 +1046,7 @@ fn test_nonce_lock() { #[test] fn send_and_refund_erc721_maker_payment_timelock() { - thread::sleep(Duration::from_secs(45)); + thread::sleep(Duration::from_secs(39)); let token_id = 2u32; let time_lock_to_refund = now_sec() - 1000; let setup = setup_test( From 1e050d2fa0046029aa309c46f687175bfa511936 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 8 Jul 2024 16:12:25 +0700 Subject: [PATCH 078/233] fmt code after merge --- mm2src/mm2_main/tests/docker_tests_main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests_main.rs b/mm2src/mm2_main/tests/docker_tests_main.rs index 4a216922de..94296d2c6f 100644 --- a/mm2src/mm2_main/tests/docker_tests_main.rs +++ b/mm2src/mm2_main/tests/docker_tests_main.rs @@ -22,8 +22,8 @@ extern crate serde_json; #[cfg(test)] extern crate ser_error_derive; #[cfg(test)] extern crate test; -use std::env; use common::custom_futures::timeout::FutureTimerExt; +use std::env; use std::io::{BufRead, BufReader}; use std::process::Command; use std::time::Duration; From fa3f553b4c1c3fc259e49d1b94ca6d4f8742ade8 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 8 Jul 2024 16:20:36 +0700 Subject: [PATCH 079/233] fix merge conflicts --- .../tests/docker_tests/docker_tests_common.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index e58e91de6e..140f5cdba0 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -41,14 +41,9 @@ use script::Builder; use secp256k1::Secp256k1; pub use secp256k1::{PublicKey, SecretKey}; use serde_json::{self as json, Value as Json}; -pub use std::env; -use std::path::PathBuf; -use std::process::Command; -use std::process::Stdio; -use std::str::FromStr; -use std::sync::Mutex; -pub use std::thread; -use std::{path::PathBuf, process::Command, str::FromStr, sync::Mutex, time::Duration}; +use std::process::{Command, Stdio}; +pub use std::{env, thread}; +use std::{path::PathBuf, str::FromStr, sync::Mutex, time::Duration}; use testcontainers::{clients::Cli, core::WaitFor, Container, GenericImage, RunnableImage}; use web3::types::{Address as EthAddress, BlockId, BlockNumber, TransactionRequest}; use web3::{transports::Http, Web3}; From eddeb1af4cad4a213d33b5909e58ba103b32b4e4 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 10 Jul 2024 12:15:27 +0700 Subject: [PATCH 080/233] make "proxy_auth" Optional --- mm2src/coins/nft/nft_structs.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mm2src/coins/nft/nft_structs.rs b/mm2src/coins/nft/nft_structs.rs index 92e9c62d30..6cc5b13c61 100644 --- a/mm2src/coins/nft/nft_structs.rs +++ b/mm2src/coins/nft/nft_structs.rs @@ -98,6 +98,7 @@ pub struct RefreshMetadataReq { /// URL used to validate if the fetched contract addresses are associated /// with spam contracts or if domain fields in the fetched metadata match known phishing domains. pub(crate) url_antispam: Url, + #[serde(default)] pub(crate) proxy_auth: bool, } @@ -661,6 +662,7 @@ pub struct UpdateNftReq { /// URL used to validate if the fetched contract addresses are associated /// with spam contracts or if domain fields in the fetched metadata match known phishing domains. pub(crate) url_antispam: Url, + #[serde(default)] pub(crate) proxy_auth: bool, } From 49c14504cb0342e3b633cd2a2f66c77fe6c1f966 Mon Sep 17 00:00:00 2001 From: laruh Date: Sat, 13 Jul 2024 21:56:23 +0700 Subject: [PATCH 081/233] eth docker tests: use eth_coin_from_conf_and_request_v2 func in global NFT test setup --- mm2src/coins/eth.rs | 35 +++++ .../tests/docker_tests/eth_docker_tests.rs | 132 ++++++++++++++---- 2 files changed, 136 insertions(+), 31 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 86c9aab0ea..a736f8c439 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7171,3 +7171,38 @@ impl TakerCoinSwapOpsV2 for EthCoin { } } } + +#[cfg(all(feature = "for-tests", not(target_arch = "wasm32")))] +impl EthCoin { + pub async fn set_coin_type(&self, ctx: &MmArc, new_coin_type: EthCoinType) -> EthCoin { + let coin = EthCoinImpl { + ticker: self.ticker.clone(), + coin_type: new_coin_type, + priv_key_policy: self.priv_key_policy.clone(), + derivation_method: Arc::clone(&self.derivation_method), + sign_message_prefix: self.sign_message_prefix.clone(), + swap_contract_address: self.swap_contract_address, + swap_v2_contracts: self.swap_v2_contracts, + fallback_swap_contract: self.fallback_swap_contract, + contract_supports_watchers: self.contract_supports_watchers, + web3_instances: AsyncMutex::new(self.web3_instances.lock().await.clone()), + decimals: self.decimals, + history_sync_state: Mutex::new(self.history_sync_state.lock().unwrap().clone()), + required_confirmations: AtomicU64::new( + self.required_confirmations.load(std::sync::atomic::Ordering::SeqCst), + ), + swap_txfee_policy: Mutex::new(self.swap_txfee_policy.lock().unwrap().clone()), + max_eth_tx_type: self.max_eth_tx_type, + ctx: ctx.weak(), + chain_id: self.chain_id, + trezor_coin: self.trezor_coin.clone(), + logs_block_range: self.logs_block_range, + address_nonce_locks: Arc::clone(&self.address_nonce_locks), + erc20_tokens_infos: Arc::clone(&self.erc20_tokens_infos), + nfts_infos: Arc::clone(&self.nfts_infos), + platform_fee_estimator_state: Arc::clone(&self.platform_fee_estimator_state), + abortable_system: self.abortable_system.create_subsystem().unwrap(), + }; + EthCoin(Arc::new(coin)) + } +} diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 38b2075c13..7e4f4d8b6e 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -7,7 +7,9 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC7 use crate::common::Future01CompatExt; use bitcrypto::{dhash160, sha256}; use coins::eth::gas_limit::ETH_MAX_TRADE_GAS; -use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_request, EthCoin, SignedEthTx, ERC20_ABI}; +use coins::eth::v2_activation::{eth_coin_from_conf_and_request_v2, EthActivationV2Request, EthNode}; +use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_request, EthCoin, EthCoinType, + EthPrivKeyBuildPolicy, SignedEthTx, SwapV2Contracts, ERC20_ABI}; use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, ConfirmPaymentInput, DerivationMethod, Eip1559Ops, FoundSwapTxSpend, MakerNftSwapOpsV2, MarketCoinOps, MmCoinEnum, MmCoinStruct, NftSwapInfo, @@ -20,7 +22,7 @@ use crypto::Secp256k1Secret; use ethcore_transaction::Action; use ethereum_types::U256; use futures01::Future; -use mm2_core::mm_ctx::MmArc; +use mm2_core::mm_ctx::{MmArc, MmCtxBuilder}; use mm2_number::{BigDecimal, BigUint}; use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, nft_dev_conf, nft_sepolia_conf}; use std::thread; @@ -45,13 +47,11 @@ pub fn geth_account() -> Address { unsafe { GETH_ACCOUNT } } /// GETH_SWAP_CONTRACT is set once during initialization before tests start pub fn swap_contract() -> Address { unsafe { GETH_SWAP_CONTRACT } } -#[allow(dead_code)] /// # Safety /// /// GETH_MAKER_SWAP_V2 is set once during initialization before tests start pub fn maker_swap_v2() -> Address { unsafe { GETH_MAKER_SWAP_V2 } } -#[allow(dead_code)] /// # Safety /// /// GETH_TAKER_SWAP_V2 is set once during initialization before tests start @@ -358,27 +358,55 @@ pub enum TestNftType { /// Generates a global NFT coin instance with a random private key and an initial 100 ETH balance. /// Optionally mints a specified NFT (either ERC721 or ERC1155) to the global NFT address, /// with details recorded in the `nfts_infos` field based on the provided `nft_type`. -pub fn global_nft_with_random_privkey(swap_contract_address: Address, nft_type: Option) -> EthCoin { - let nft_conf = nft_dev_conf(); - let req = json!({ - "method": "enable", - "coin": "NFT_ETH", - "urls": [GETH_RPC_URL], - "swap_contract_address": swap_contract_address, +pub fn global_nft_with_random_privkey( + swap_v2_contracts: SwapV2Contracts, + swap_contract_address: Address, + fallback_swap_contract_address: Address, + nft_type: Option, + nft_ticker: String, + platform_ticker: String, +) -> EthCoin { + let coins = json!([eth_dev_conf(), nft_dev_conf()]); + let conf = json!({ + "coins": coins, + "use_trading_proto_v2": true, }); + let ctx = MmCtxBuilder::new().with_conf(conf).into_mm_arc(); + let build_policy = EthPrivKeyBuildPolicy::IguanaPrivKey(random_secp256k1_secret()); + let node = EthNode { + url: GETH_RPC_URL.to_string(), + gui_auth: false, + }; + let platform_request = EthActivationV2Request { + nodes: vec![node], + rpc_mode: Default::default(), + swap_contract_address, + swap_v2_contracts: Some(swap_v2_contracts), + fallback_swap_contract: Some(fallback_swap_contract_address), + contract_supports_watchers: false, + mm2: None, + required_confirmations: None, + priv_key_policy: Default::default(), + enable_params: Default::default(), + path_to_address: Default::default(), + gap_limit: None, + }; - let global_nft = block_on(eth_coin_from_conf_and_request( - &MM_CTX, - "NFT_ETH", - &nft_conf, - &req, - CoinProtocol::NFT { - platform: "ETH".to_string(), - }, - PrivKeyBuildPolicy::IguanaPrivKey(random_secp256k1_secret()), + let coin = block_on(eth_coin_from_conf_and_request_v2( + &ctx, + nft_ticker.as_str(), + &nft_dev_conf(), + platform_request, + build_policy, )) .unwrap(); + let coin_type = EthCoinType::Nft { + platform: platform_ticker, + }; + + let global_nft = block_on(coin.set_coin_type(&ctx, coin_type)); + let my_address = block_on(global_nft.my_addr()); fill_eth(my_address, U256::from(10).pow(U256::from(20))); @@ -939,13 +967,14 @@ fn send_and_spend_erc721_maker_payment() { thread::sleep(Duration::from_secs(11)); let token_id = 1u32; let time_lock = now_sec() + 1000; + let activation = NftActivationV2Args::init(); let setup = setup_test( token_id, None, ContractType::Erc721, - geth_nft_maker_swap_v2(), geth_erc721_contract(), time_lock, + activation, ); let maker_payment = send_nft_maker_payment(&setup, 1.into()); @@ -975,13 +1004,14 @@ fn send_and_spend_erc1155_maker_payment() { let token_id = 1u32; let amount = 3u32; let time_lock = now_sec() + 1000; + let activation = NftActivationV2Args::init(); let setup = setup_test( token_id, Some(amount), ContractType::Erc1155, - geth_nft_maker_swap_v2(), geth_erc1155_contract(), time_lock, + activation, ); let maker_address = block_on(setup.maker_global_nft.my_addr()); @@ -1049,13 +1079,14 @@ fn send_and_refund_erc721_maker_payment_timelock() { thread::sleep(Duration::from_secs(39)); let token_id = 2u32; let time_lock_to_refund = now_sec() - 1000; + let activation = NftActivationV2Args::init(); let setup = setup_test( token_id, None, ContractType::Erc721, - geth_nft_maker_swap_v2(), geth_erc721_contract(), time_lock_to_refund, + activation, ); let maker_payment_to_refund = send_nft_maker_payment(&setup, 1.into()); @@ -1091,13 +1122,14 @@ fn send_and_refund_erc1155_maker_payment_timelock() { let token_id = 2u32; let amount = 3u32; let time_lock_to_refund = now_sec() - 1000; + let activation = NftActivationV2Args::init(); let setup = setup_test( token_id, Some(amount), ContractType::Erc1155, - geth_nft_maker_swap_v2(), geth_erc1155_contract(), time_lock_to_refund, + activation, ); let maker_address = block_on(setup.maker_global_nft.my_addr()); @@ -1140,14 +1172,14 @@ fn send_and_refund_erc721_maker_payment_secret() { thread::sleep(Duration::from_secs(5)); let token_id = 3u32; let time_lock_to_refund = now_sec() + 1000; - + let activation = NftActivationV2Args::init(); let setup = setup_test( token_id, None, ContractType::Erc721, - geth_nft_maker_swap_v2(), geth_erc721_contract(), time_lock_to_refund, + activation, ); let maker_payment_to_refund = send_nft_maker_payment(&setup, 1.into()); @@ -1183,13 +1215,14 @@ fn send_and_refund_erc1155_maker_payment_secret() { let token_id = 3u32; let amount = 3u32; let time_lock_to_refund = now_sec() + 1000; + let activation = NftActivationV2Args::init(); let setup = setup_test( token_id, Some(amount), ContractType::Erc1155, - geth_nft_maker_swap_v2(), geth_erc1155_contract(), time_lock_to_refund, + activation, ); let maker_address = block_on(setup.maker_global_nft.my_addr()); @@ -1249,14 +1282,37 @@ pub struct TestNftSwapInfo { /// Etomic swap contract address pub swap_contract_address: Coin::ContractAddress, } +struct NftActivationV2Args { + swap_contract_address: Address, + fallback_swap_contract_address: Address, + swap_v2_contracts: SwapV2Contracts, + nft_ticker: String, + platform_ticker: String, +} + +impl NftActivationV2Args { + fn init() -> Self { + Self { + swap_contract_address: swap_contract(), + fallback_swap_contract_address: swap_contract(), + swap_v2_contracts: SwapV2Contracts { + maker_swap_v2_contract: maker_swap_v2(), + taker_swap_v2_contract: taker_swap_v2(), + nft_maker_swap_v2_contract: geth_nft_maker_swap_v2(), + }, + nft_ticker: "NFT_ETH".to_string(), + platform_ticker: "ETH".to_string(), + } + } +} fn setup_test( token_id: u32, amount: Option, contract_type: ContractType, - swap_contract_address: Address, token_contract: Address, time_lock: u64, + activation: NftActivationV2Args, ) -> NftTestSetup { let nft_type = match contract_type { ContractType::Erc721 => TestNftType::Erc721 { token_id }, @@ -1266,8 +1322,22 @@ fn setup_test( }, }; - let maker_global_nft = global_nft_with_random_privkey(swap_contract_address, Some(nft_type)); - let taker_global_nft = global_nft_with_random_privkey(swap_contract_address, None); + let maker_global_nft = global_nft_with_random_privkey( + activation.swap_v2_contracts, + activation.swap_contract_address, + activation.fallback_swap_contract_address, + Some(nft_type), + activation.nft_ticker.clone(), + activation.platform_ticker.clone(), + ); + let taker_global_nft = global_nft_with_random_privkey( + activation.swap_v2_contracts, + activation.swap_contract_address, + activation.fallback_swap_contract_address, + None, + activation.nft_ticker, + activation.platform_ticker, + ); let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); let taker_secret = vec![0; 32]; @@ -1279,7 +1349,7 @@ fn setup_test( token_address: token_contract, token_id, contract_type, - swap_contract_address, + swap_contract_address: activation.swap_v2_contracts.nft_maker_swap_v2_contract, }; NftTestSetup { From 5971601318d90d63c20ce1d89a52cfc776c69292 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 14 Jul 2024 08:11:11 +0700 Subject: [PATCH 082/233] eth docker tests: set global MM_CTX in set_coin_type --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 7e4f4d8b6e..11737a0e74 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -405,7 +405,7 @@ pub fn global_nft_with_random_privkey( platform: platform_ticker, }; - let global_nft = block_on(coin.set_coin_type(&ctx, coin_type)); + let global_nft = block_on(coin.set_coin_type(&MM_CTX, coin_type)); let my_address = block_on(global_nft.my_addr()); fill_eth(my_address, U256::from(10).pow(U256::from(20))); From 647f4259dfa48e372fd6f027d1d04d5154643c38 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 14 Jul 2024 19:31:15 +0700 Subject: [PATCH 083/233] eth docker tests: init global MM_CTX1 with config --- mm2src/coins/eth.rs | 4 ++-- .../tests/docker_tests/docker_tests_common.rs | 2 +- .../mm2_main/tests/docker_tests/eth_docker_tests.rs | 12 +++--------- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index a736f8c439..76b0e0990d 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7174,7 +7174,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { #[cfg(all(feature = "for-tests", not(target_arch = "wasm32")))] impl EthCoin { - pub async fn set_coin_type(&self, ctx: &MmArc, new_coin_type: EthCoinType) -> EthCoin { + pub async fn set_coin_type(&self, new_coin_type: EthCoinType) -> EthCoin { let coin = EthCoinImpl { ticker: self.ticker.clone(), coin_type: new_coin_type, @@ -7193,7 +7193,7 @@ impl EthCoin { ), swap_txfee_policy: Mutex::new(self.swap_txfee_policy.lock().unwrap().clone()), max_eth_tx_type: self.max_eth_tx_type, - ctx: ctx.weak(), + ctx: self.ctx.clone(), chain_id: self.chain_id, trezor_coin: self.trezor_coin.clone(), logs_block_range: self.logs_block_range, diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 140f5cdba0..ee2cbbb1da 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -64,7 +64,7 @@ lazy_static! { /// This means that different instances of the same coin should have separate global nonce locks. /// Utilizing different `MmCtx` instances allows us to assign Maker and Taker coins to separate `CoinsCtx`. /// This approach addresses the `replacement transaction` issue, which occurs when different transactions share the same nonce. - pub static ref MM_CTX1: MmArc = MmCtxBuilder::new().into_mm_arc(); + pub static ref MM_CTX1: MmArc = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); pub static ref GETH_WEB3: Web3 = Web3::new(Http::new(GETH_RPC_URL).unwrap()); pub static ref SEPOLIA_WEB3: Web3 = Web3::new(Http::new(SEPOLIA_RPC_URL).unwrap()); // Mutex used to prevent nonce re-usage during funding addresses used in tests diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 11737a0e74..0fe5e53063 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -2,7 +2,7 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC7 GETH_ERC1155_CONTRACT, GETH_ERC20_CONTRACT, GETH_ERC721_CONTRACT, GETH_MAKER_SWAP_V2, GETH_NFT_MAKER_SWAP_V2, GETH_NFT_SWAP_CONTRACT, GETH_NONCE_LOCK, GETH_RPC_URL, GETH_SWAP_CONTRACT, GETH_TAKER_SWAP_V2, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, - MM_CTX, SEPOLIA_ERC1155_CONTRACT, SEPOLIA_ERC721_CONTRACT, + MM_CTX, MM_CTX1, SEPOLIA_ERC1155_CONTRACT, SEPOLIA_ERC721_CONTRACT, SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2, SEPOLIA_NONCE_LOCK, SEPOLIA_RPC_URL, SEPOLIA_WEB3}; use crate::common::Future01CompatExt; use bitcrypto::{dhash160, sha256}; @@ -366,12 +366,6 @@ pub fn global_nft_with_random_privkey( nft_ticker: String, platform_ticker: String, ) -> EthCoin { - let coins = json!([eth_dev_conf(), nft_dev_conf()]); - let conf = json!({ - "coins": coins, - "use_trading_proto_v2": true, - }); - let ctx = MmCtxBuilder::new().with_conf(conf).into_mm_arc(); let build_policy = EthPrivKeyBuildPolicy::IguanaPrivKey(random_secp256k1_secret()); let node = EthNode { url: GETH_RPC_URL.to_string(), @@ -393,7 +387,7 @@ pub fn global_nft_with_random_privkey( }; let coin = block_on(eth_coin_from_conf_and_request_v2( - &ctx, + &MM_CTX1, nft_ticker.as_str(), &nft_dev_conf(), platform_request, @@ -405,7 +399,7 @@ pub fn global_nft_with_random_privkey( platform: platform_ticker, }; - let global_nft = block_on(coin.set_coin_type(&MM_CTX, coin_type)); + let global_nft = block_on(coin.set_coin_type(coin_type)); let my_address = block_on(global_nft.my_addr()); fill_eth(my_address, U256::from(10).pow(U256::from(20))); From af70871cd77e60f26dae7b33d4abdaf8333e66a6 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 14 Jul 2024 19:47:41 +0700 Subject: [PATCH 084/233] eth docker tests: change sleep duration --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 0fe5e53063..fdd34bf3b6 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -22,7 +22,7 @@ use crypto::Secp256k1Secret; use ethcore_transaction::Action; use ethereum_types::U256; use futures01::Future; -use mm2_core::mm_ctx::{MmArc, MmCtxBuilder}; +use mm2_core::mm_ctx::MmArc; use mm2_number::{BigDecimal, BigUint}; use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, nft_dev_conf, nft_sepolia_conf}; use std::thread; @@ -1070,7 +1070,7 @@ fn test_nonce_lock() { #[test] fn send_and_refund_erc721_maker_payment_timelock() { - thread::sleep(Duration::from_secs(39)); + thread::sleep(Duration::from_secs(33)); let token_id = 2u32; let time_lock_to_refund = now_sec() - 1000; let activation = NftActivationV2Args::init(); @@ -1205,7 +1205,7 @@ fn send_and_refund_erc721_maker_payment_secret() { #[test] fn send_and_refund_erc1155_maker_payment_secret() { - thread::sleep(Duration::from_secs(2)); + thread::sleep(Duration::from_secs(4)); let token_id = 3u32; let amount = 3u32; let time_lock_to_refund = now_sec() + 1000; From ceeaac5436beb45f0588225d5290d7e00d73a73c Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 14 Jul 2024 21:10:15 +0700 Subject: [PATCH 085/233] eth tpu v2: refund_taker_funding_secret ETH part --- mm2src/coins/eth.rs | 4 +- mm2src/coins/eth/eth_swap_v2.rs | 84 ++++++++++++++++++- .../tests/docker_tests/eth_docker_tests.rs | 2 +- 3 files changed, 86 insertions(+), 4 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 76b0e0990d..e5ab1dc4c5 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7059,9 +7059,9 @@ impl TakerCoinSwapOpsV2 for EthCoin { async fn refund_taker_funding_secret( &self, - _args: RefundFundingSecretArgs<'_, Self>, + args: RefundFundingSecretArgs<'_, Self>, ) -> Result { - todo!() + self.refund_taker_funding_secret_impl(args).await } async fn search_for_taker_funding_spend( diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 4fa8b8154b..0adf12ef6a 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,10 +1,11 @@ use super::eth::{addr_from_raw_pubkey, gas_limit, wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; -use super::{SendTakerFundingArgs, Transaction, TransactionErr}; +use super::{RefundFundingSecretArgs, SendTakerFundingArgs, Transaction, TransactionErr}; use enum_derives::EnumFromStringify; use ethabi::Token; use ethcore_transaction::Action; use ethereum_types::{Address, U256}; +use ethkey::public_to_address; use futures::compat::Future01CompatExt; use std::convert::TryInto; @@ -18,6 +19,16 @@ struct TakerFundingArgs<'a> { payment_time_lock: u32, } +struct TakerRefundSecretArgs<'a> { + dex_fee: U256, + payment_amount: U256, + maker_address: Address, + taker_secret: &'a [u8], + maker_secret_hash: &'a [u8], + funding_time_lock: u32, + payment_time_lock: u32, +} + impl EthCoin { pub(crate) async fn send_taker_funding_impl( &self, @@ -111,6 +122,59 @@ impl EthCoin { } } + pub(crate) async fn refund_taker_funding_secret_impl( + &self, + args: RefundFundingSecretArgs<'_, Self>, + ) -> Result { + let taker_swap_v2_contract = self + .swap_v2_contracts + .as_ref() + .map(|contracts| contracts.taker_swap_v2_contract) + .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; + let dex_fee = try_tx_s!(wei_from_big_decimal( + &args.dex_fee.fee_amount().to_decimal(), + self.decimals + )); + let payment_amount = try_tx_s!(wei_from_big_decimal( + &(args.trading_amount + args.premium_amount), + self.decimals + )); + let maker_address = public_to_address(args.maker_pubkey); + let funding_time_lock: u32 = try_tx_s!(args.funding_time_lock.try_into()); + let payment_time_lock: u32 = try_tx_s!(args.payment_time_lock.try_into()); + let refund_args = TakerRefundSecretArgs { + dex_fee, + payment_amount, + maker_address, + taker_secret: args.taker_secret, + maker_secret_hash: args.maker_secret_hash, + funding_time_lock, + payment_time_lock, + }; + match &self.coin_type { + EthCoinType::Eth => { + let data = try_tx_s!(self.prepare_taker_refund_eth_secret_data(&refund_args).await); + self.sign_and_send_transaction( + payment_amount, + Action::Call(taker_swap_v2_contract), + data, + U256::from(gas_limit::ETH_PAYMENT), + ) + .compat() + .await + }, + EthCoinType::Erc20 { + platform: _, + token_addr: _, + } => { + todo!() + }, + EthCoinType::Nft { .. } => Err(TransactionErr::ProtocolNotSupported( + "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), + )), + } + } + async fn prepare_taker_eth_funding_data(&self, args: &TakerFundingArgs<'_>) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("ethTakerPayment")?; let id = self.etomic_swap_v2_id(args.funding_time_lock, args.payment_time_lock, args.taker_secret_hash); @@ -146,6 +210,24 @@ impl EthCoin { ])?; Ok(data) } + + async fn prepare_taker_refund_eth_secret_data( + &self, + args: &TakerRefundSecretArgs<'_>, + ) -> Result, PrepareTxDataError> { + let function = TAKER_SWAP_V2.function("refundTakerPaymentSecret")?; + let id = self.etomic_swap_v2_id(args.funding_time_lock, args.payment_time_lock, args.taker_secret); + let data = function.encode_input(&[ + Token::FixedBytes(id), + Token::Uint(args.payment_amount), + Token::Uint(args.dex_fee), + Token::Address(args.maker_address), + Token::FixedBytes(args.taker_secret.to_vec()), + Token::FixedBytes(args.maker_secret_hash.to_vec()), + Token::Address(Address::default()), + ])?; + Ok(data) + } } #[allow(dead_code)] diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index fdd34bf3b6..310a1d94c4 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1294,7 +1294,7 @@ impl NftActivationV2Args { taker_swap_v2_contract: taker_swap_v2(), nft_maker_swap_v2_contract: geth_nft_maker_swap_v2(), }, - nft_ticker: "NFT_ETH".to_string(), + nft_ticker: NFT_ETH.to_string(), platform_ticker: "ETH".to_string(), } } From bb39b36f9e32f7afe820b34ccb76cc9a648c223c Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 15 Jul 2024 16:26:55 +0700 Subject: [PATCH 086/233] eth tpu v2: refund_taker_funding_secret ETH and ERC20 parts impl --- mm2src/coins/eth/eth_swap_v2.rs | 62 ++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 0adf12ef6a..471bd89d77 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -153,21 +153,35 @@ impl EthCoin { }; match &self.coin_type { EthCoinType::Eth => { - let data = try_tx_s!(self.prepare_taker_refund_eth_secret_data(&refund_args).await); + let data = try_tx_s!( + self.prepare_taker_refund_payment_secret_data(&refund_args, Address::default()) + .await + ); self.sign_and_send_transaction( payment_amount, Action::Call(taker_swap_v2_contract), data, - U256::from(gas_limit::ETH_PAYMENT), + U256::from(gas_limit::ETH_SENDER_REFUND), ) .compat() .await }, EthCoinType::Erc20 { platform: _, - token_addr: _, + token_addr, } => { - todo!() + let data = try_tx_s!( + self.prepare_taker_refund_payment_secret_data(&refund_args, *token_addr) + .await + ); + self.sign_and_send_transaction( + payment_amount, + Action::Call(taker_swap_v2_contract), + data, + U256::from(gas_limit::ERC20_SENDER_REFUND), + ) + .compat() + .await }, EthCoinType::Nft { .. } => Err(TransactionErr::ProtocolNotSupported( "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), @@ -175,6 +189,15 @@ impl EthCoin { } } + /// Prepares data for EtomicSwapTakerV2 contract `ethTakerPayment` method + /// function ethTakerPayment( + /// bytes32 id, + /// uint256 dexFee, + /// address receiver, + /// bytes32 takerSecretHash, + /// bytes32 makerSecretHash, + /// uint32 preApproveLockTime, + /// uint32 paymentLockTime async fn prepare_taker_eth_funding_data(&self, args: &TakerFundingArgs<'_>) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("ethTakerPayment")?; let id = self.etomic_swap_v2_id(args.funding_time_lock, args.payment_time_lock, args.taker_secret_hash); @@ -190,10 +213,21 @@ impl EthCoin { Ok(data) } + /// Prepares data for EtomicSwapTakerV2 contract `erc20TakerPayment` method + /// function erc20TakerPayment( + /// bytes32 id, + /// uint256 amount, + /// uint256 dexFee, + /// address tokenAddress, + /// address receiver, + /// bytes32 takerSecretHash, + /// bytes32 makerSecretHash, + /// uint32 preApproveLockTime, + /// uint32 paymentLockTime async fn prepare_taker_erc20_funding_data( &self, args: &TakerFundingArgs<'_>, - token_addr: Address, + token_address: Address, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("erc20TakerPayment")?; let id = self.etomic_swap_v2_id(args.funding_time_lock, args.payment_time_lock, args.taker_secret_hash); @@ -201,7 +235,7 @@ impl EthCoin { Token::FixedBytes(id), Token::Uint(args.payment_amount), Token::Uint(args.dex_fee), - Token::Address(token_addr), + Token::Address(token_address), Token::Address(args.maker_address), Token::FixedBytes(args.taker_secret_hash.to_vec()), Token::FixedBytes(args.maker_secret_hash.to_vec()), @@ -211,9 +245,19 @@ impl EthCoin { Ok(data) } - async fn prepare_taker_refund_eth_secret_data( + /// Prepares data for EtomicSwapTakerV2 contract `refundTakerPaymentSecret` method + /// function refundTakerPaymentSecret( + /// bytes32 id, + /// uint256 amount, + /// uint256 dexFee, + /// address maker, + /// bytes32 takerSecret, + /// bytes32 makerSecretHash, + /// address tokenAddress + async fn prepare_taker_refund_payment_secret_data( &self, args: &TakerRefundSecretArgs<'_>, + token_address: Address, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("refundTakerPaymentSecret")?; let id = self.etomic_swap_v2_id(args.funding_time_lock, args.payment_time_lock, args.taker_secret); @@ -224,18 +268,18 @@ impl EthCoin { Token::Address(args.maker_address), Token::FixedBytes(args.taker_secret.to_vec()), Token::FixedBytes(args.maker_secret_hash.to_vec()), - Token::Address(Address::default()), + Token::Address(token_address), ])?; Ok(data) } } -#[allow(dead_code)] #[derive(Debug, Display, EnumFromStringify)] enum PrepareTxDataError { #[from_stringify("ethabi::Error")] #[display(fmt = "Abi error: {}", _0)] AbiError(String), + #[allow(dead_code)] #[display(fmt = "Internal error: {}", _0)] Internal(String), } From ac38aea559d8b21acce7bb555cb2d130c4bc130b Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 16 Jul 2024 13:03:48 +0700 Subject: [PATCH 087/233] eth tpu v2: send_and_refund_taker_funding_by_secret ETH/ERC20 tests. Remove "swap_contract_address" field from RefundFundingSecretArgs struct --- mm2src/coins/lp_coins.rs | 1 - mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 1 - .../tests/docker_tests/eth_docker_tests.rs | 174 +++++++++++++++++- .../tests/docker_tests/swap_proto_v2_tests.rs | 1 - 4 files changed, 169 insertions(+), 8 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 7d7bf1dac8..3a58b1839a 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1310,7 +1310,6 @@ pub struct RefundFundingSecretArgs<'a, Coin: ParseCoinAssocTypes + ?Sized> { pub taker_secret: &'a [u8], pub taker_secret_hash: &'a [u8], pub maker_secret_hash: &'a [u8], - pub swap_contract_address: &'a Option, /// DEX fee pub dex_fee: &'a DexFee, /// Additional reward for maker (premium) diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs index ac5edf9312..8591207385 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs @@ -1801,7 +1801,6 @@ impl Self { + Self { + swap_contract_address: swap_contract(), + fallback_swap_contract_address: swap_contract(), + swap_v2_contracts: SwapV2Contracts { + maker_swap_v2_contract: maker_swap_v2(), + taker_swap_v2_contract: taker_swap_v2(), + nft_maker_swap_v2_contract: geth_nft_maker_swap_v2(), + }, + } + } +} + +fn eth_coin_v2_activation_with_random_privkey(ticker: &str, conf: &Json, swap_addr: SwapAddresses) -> EthCoin { + let build_policy = EthPrivKeyBuildPolicy::IguanaPrivKey(random_secp256k1_secret()); + let node = EthNode { + url: GETH_RPC_URL.to_string(), + gui_auth: false, + }; + let platform_request = EthActivationV2Request { + nodes: vec![node], + rpc_mode: Default::default(), + swap_contract_address: swap_addr.swap_contract_address, + swap_v2_contracts: Some(swap_addr.swap_v2_contracts), + fallback_swap_contract: Some(swap_addr.fallback_swap_contract_address), + contract_supports_watchers: false, + mm2: None, + required_confirmations: None, + priv_key_policy: Default::default(), + enable_params: Default::default(), + path_to_address: Default::default(), + gap_limit: None, + }; + let coin = block_on(eth_coin_from_conf_and_request_v2( + &MM_CTX1, + ticker, + conf, + platform_request, + build_policy, + )) + .unwrap(); + let my_address = block_on(coin.my_addr()); + fill_eth(my_address, U256::from(10).pow(U256::from(20))); + coin +} + +#[test] +fn send_and_refund_taker_funding_by_secret_eth() { + let taker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init()); + let maker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init()); + + let taker_secret = vec![0; 32]; + let taker_secret_hash = sha256(&taker_secret).to_vec(); + let maker_secret = vec![1; 32]; + let maker_secret_hash = sha256(&maker_secret).to_vec(); + let funding_time_lock = now_sec() + 3000; + let payment_time_lock = now_sec() + 1000; + + let dex_fee = &DexFee::Standard("0.1".into()); + let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); + let payment_args = SendTakerFundingArgs { + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + maker_pub: maker_pub.as_bytes(), + dex_fee, + premium_amount: BigDecimal::default(), + trading_amount: 1.into(), + swap_unique_data: &[], + wait_for_confirmation_until: 0, + }; + let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); + log!("Taker sent ETH Funding, tx hash: {:02x}", funding_tx.tx_hash()); + + // TODO call validation function when implemented + + let refund_args = RefundFundingSecretArgs { + funding_tx: &funding_tx, + funding_time_lock, + payment_time_lock, + maker_pubkey: &taker_coin.derive_htlc_pubkey_v2(&[]), + taker_secret: &taker_secret, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + dex_fee, + premium_amount: Default::default(), + trading_amount: 1.into(), + swap_unique_data: &[], + watcher_reward: false, + }; + let funding_tx_refund = block_on(taker_coin.refund_taker_funding_secret(refund_args)).unwrap(); + log!( + "Taker refined ETH Funding by Secret, tx hash: {:02x}", + funding_tx_refund.tx_hash() + ); +} + +#[test] +fn send_and_refund_taker_funding_by_secret_erc20() { + let erc20_conf = &erc20_dev_conf(&erc20_contract_checksum()); + let taker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init()); + let maker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init()); + + let taker_secret = vec![0; 32]; + let taker_secret_hash = sha256(&taker_secret).to_vec(); + let maker_secret = vec![1; 32]; + let maker_secret_hash = sha256(&maker_secret).to_vec(); + let funding_time_lock = now_sec() + 3000; + let payment_time_lock = now_sec() + 1000; + + let dex_fee = &DexFee::Standard("0.1".into()); + let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); + let payment_args = SendTakerFundingArgs { + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + maker_pub: maker_pub.as_bytes(), + dex_fee, + premium_amount: BigDecimal::default(), + trading_amount: 1.into(), + swap_unique_data: &[], + wait_for_confirmation_until: 70, + }; + + let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); + log!("Taker sent ERC20 Funding, tx hash {:02x}", funding_tx.tx_hash()); + + // TODO call validation function when implemented + + let refund_args = RefundFundingSecretArgs { + funding_tx: &funding_tx, + funding_time_lock, + payment_time_lock, + maker_pubkey: &taker_coin.derive_htlc_pubkey_v2(&[]), + taker_secret: &taker_secret, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + dex_fee, + premium_amount: Default::default(), + trading_amount: 1.into(), + swap_unique_data: &[], + watcher_reward: false, + }; + let funding_tx_refund = block_on(taker_coin.refund_taker_funding_secret(refund_args)).unwrap(); + log!( + "Taker refined ERC20 Funding by Secret, tx hash: {:02x}", + funding_tx_refund.tx_hash() + ); +} diff --git a/mm2src/mm2_main/tests/docker_tests/swap_proto_v2_tests.rs b/mm2src/mm2_main/tests/docker_tests/swap_proto_v2_tests.rs index 111b1d3409..f878d1ed0e 100644 --- a/mm2src/mm2_main/tests/docker_tests/swap_proto_v2_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/swap_proto_v2_tests.rs @@ -157,7 +157,6 @@ fn send_and_refund_taker_funding_secret() { taker_secret: &taker_secret, taker_secret_hash, maker_secret_hash: &[], - swap_contract_address: &None, dex_fee, premium_amount: "0.1".parse().unwrap(), trading_amount: 1.into(), From c64af3b2296df34e87c5fcda7ce5ef5edea9ae6e Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 16 Jul 2024 13:29:28 +0700 Subject: [PATCH 088/233] eth tpu v2: add wait_for_confirmations in send_and_refund_taker_funding_by_secret ETH/ERC20 tests --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 359a62f1f7..e082b41fb2 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1382,7 +1382,7 @@ fn send_nft_maker_payment(setup: &NftTestSetup, amount: BigDecimal) -> SignedEth block_on(setup.maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap() } -fn wait_for_confirmations(global_nft: &EthCoin, tx: &SignedEthTx, wait_seconds: u64) { +fn wait_for_confirmations(coin: &EthCoin, tx: &SignedEthTx, wait_seconds: u64) { let confirm_input = ConfirmPaymentInput { payment_tx: tx.tx_hex(), confirmations: 1, @@ -1390,7 +1390,7 @@ fn wait_for_confirmations(global_nft: &EthCoin, tx: &SignedEthTx, wait_seconds: wait_until: now_sec() + wait_seconds, check_every: 1, }; - global_nft.wait_for_confirmations(confirm_input).wait().unwrap(); + coin.wait_for_confirmations(confirm_input).wait().unwrap(); } fn validate_nft_maker_payment(setup: &NftTestSetup, maker_payment: &SignedEthTx, amount: BigDecimal) { @@ -1548,7 +1548,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ETH Funding, tx hash: {:02x}", funding_tx.tx_hash()); - // TODO call validation function when implemented + wait_for_confirmations(&taker_coin, &funding_tx, 60); let refund_args = RefundFundingSecretArgs { funding_tx: &funding_tx, @@ -1602,7 +1602,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ERC20 Funding, tx hash {:02x}", funding_tx.tx_hash()); - // TODO call validation function when implemented + wait_for_confirmations(&taker_coin, &funding_tx, 60); let refund_args = RefundFundingSecretArgs { funding_tx: &funding_tx, From bac63a90b36db6a99945ce6bb6b0b0e967f0a26c Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 16 Jul 2024 14:09:56 +0700 Subject: [PATCH 089/233] eth tpu v2: use public_to_address function --- mm2src/coins/eth/eth_swap_v2.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 471bd89d77..906fd0aa5a 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,10 +1,9 @@ -use super::eth::{addr_from_raw_pubkey, gas_limit, wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, - TAKER_SWAP_V2}; +use super::eth::{gas_limit, wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; use super::{RefundFundingSecretArgs, SendTakerFundingArgs, Transaction, TransactionErr}; use enum_derives::EnumFromStringify; use ethabi::Token; use ethcore_transaction::Action; -use ethereum_types::{Address, U256}; +use ethereum_types::{Address, Public, U256}; use ethkey::public_to_address; use futures::compat::Future01CompatExt; use std::convert::TryInto; @@ -45,7 +44,9 @@ impl EthCoin { &(args.trading_amount + args.premium_amount), self.decimals )); - let maker_address = try_tx_s!(addr_from_raw_pubkey(args.maker_pub)); + // TODO add legacy derive_htlc_pubkey support additionally? + // as derive_htlc_pubkey_v2 function is used for swap_v2, we can call public_to_address + let maker_address = public_to_address(&Public::from_slice(args.maker_pub)); let funding_time_lock: u32 = try_tx_s!(args.funding_time_lock.try_into()); let payment_time_lock: u32 = try_tx_s!(args.payment_time_lock.try_into()); From 5c0361f16d287638b9cabaa8ecd29902e12c0df1 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 16 Jul 2024 14:16:31 +0700 Subject: [PATCH 090/233] fix typo and add now_sec() --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index e082b41fb2..7ea72c73b7 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1566,7 +1566,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { }; let funding_tx_refund = block_on(taker_coin.refund_taker_funding_secret(refund_args)).unwrap(); log!( - "Taker refined ETH Funding by Secret, tx hash: {:02x}", + "Taker refunded ETH Funding by Secret, tx hash: {:02x}", funding_tx_refund.tx_hash() ); } @@ -1596,7 +1596,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { premium_amount: BigDecimal::default(), trading_amount: 1.into(), swap_unique_data: &[], - wait_for_confirmation_until: 70, + wait_for_confirmation_until: now_sec() + 60, }; let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); @@ -1620,7 +1620,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { }; let funding_tx_refund = block_on(taker_coin.refund_taker_funding_secret(refund_args)).unwrap(); log!( - "Taker refined ERC20 Funding by Secret, tx hash: {:02x}", + "Taker refunded ERC20 Funding by Secret, tx hash: {:02x}", funding_tx_refund.tx_hash() ); } From 49f435da5e24384c7082ff853ea807665b8ffb99 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 16 Jul 2024 15:17:39 +0700 Subject: [PATCH 091/233] eth tpu v2: refund_taker_funding_timelock WIP --- mm2src/coins/eth.rs | 4 ++-- mm2src/coins/eth/eth_swap_v2.rs | 14 +++++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index e5ab1dc4c5..365044b436 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7053,8 +7053,8 @@ impl TakerCoinSwapOpsV2 for EthCoin { todo!() } - async fn refund_taker_funding_timelock(&self, _args: RefundPaymentArgs<'_>) -> Result { - todo!() + async fn refund_taker_funding_timelock(&self, args: RefundPaymentArgs<'_>) -> Result { + self.refund_taker_funding_timelock_impl(args).await } async fn refund_taker_funding_secret( diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 906fd0aa5a..be36a78699 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,5 +1,5 @@ use super::eth::{gas_limit, wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; -use super::{RefundFundingSecretArgs, SendTakerFundingArgs, Transaction, TransactionErr}; +use super::{RefundFundingSecretArgs, RefundPaymentArgs, SendTakerFundingArgs, Transaction, TransactionErr}; use enum_derives::EnumFromStringify; use ethabi::Token; use ethcore_transaction::Action; @@ -123,6 +123,18 @@ impl EthCoin { } } + pub(crate) async fn refund_taker_funding_timelock_impl( + &self, + _args: RefundPaymentArgs<'_>, + ) -> Result { + let _taker_swap_v2_contract = self + .swap_v2_contracts + .as_ref() + .map(|contracts| contracts.taker_swap_v2_contract) + .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; + todo!() + } + pub(crate) async fn refund_taker_funding_secret_impl( &self, args: RefundFundingSecretArgs<'_, Self>, From b5861b0e0a8ee41e1056c1a5f09f76d453d7909f Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 17 Jul 2024 17:53:02 +0700 Subject: [PATCH 092/233] eth tpu v2: replace RefundPaymentArgs by RefundTakerPaymentArgs in TakerCoinSwapOpsV2 --- mm2src/coins/eth.rs | 10 ++++-- mm2src/coins/eth/eth_swap_v2.rs | 17 ++++++++-- mm2src/coins/lp_coins.rs | 33 ++++++++++++++++--- mm2src/coins/test_coin.rs | 14 +++++--- mm2src/coins/utxo/utxo_standard.rs | 30 +++++++++++++++-- mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 14 +++++--- .../tests/docker_tests/swap_proto_v2_tests.rs | 14 +++++--- 7 files changed, 105 insertions(+), 27 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 365044b436..aa0e0bdd94 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7053,7 +7053,10 @@ impl TakerCoinSwapOpsV2 for EthCoin { todo!() } - async fn refund_taker_funding_timelock(&self, args: RefundPaymentArgs<'_>) -> Result { + async fn refund_taker_funding_timelock( + &self, + args: RefundTakerPaymentArgs<'_>, + ) -> Result { self.refund_taker_funding_timelock_impl(args).await } @@ -7105,7 +7108,10 @@ impl TakerCoinSwapOpsV2 for EthCoin { todo!() } - async fn refund_combined_taker_payment(&self, _args: RefundPaymentArgs<'_>) -> Result { + async fn refund_combined_taker_payment( + &self, + _args: RefundTakerPaymentArgs<'_>, + ) -> Result { todo!() } diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index be36a78699..63d126e771 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,5 +1,6 @@ use super::eth::{gas_limit, wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; -use super::{RefundFundingSecretArgs, RefundPaymentArgs, SendTakerFundingArgs, Transaction, TransactionErr}; +use super::{RefundFundingSecretArgs, SendTakerFundingArgs, Transaction, TransactionErr}; +use crate::RefundTakerPaymentArgs; use enum_derives::EnumFromStringify; use ethabi::Token; use ethcore_transaction::Action; @@ -44,7 +45,7 @@ impl EthCoin { &(args.trading_amount + args.premium_amount), self.decimals )); - // TODO add legacy derive_htlc_pubkey support additionally? + // TODO add maker_pub created by legacy derive_htlc_pubkey support additionally? // as derive_htlc_pubkey_v2 function is used for swap_v2, we can call public_to_address let maker_address = public_to_address(&Public::from_slice(args.maker_pub)); @@ -125,13 +126,23 @@ impl EthCoin { pub(crate) async fn refund_taker_funding_timelock_impl( &self, - _args: RefundPaymentArgs<'_>, + args: RefundTakerPaymentArgs<'_>, ) -> Result { let _taker_swap_v2_contract = self .swap_v2_contracts .as_ref() .map(|contracts| contracts.taker_swap_v2_contract) .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; + let _dex_fee = try_tx_s!(wei_from_big_decimal( + &args.dex_fee.fee_amount().to_decimal(), + self.decimals + )); + let _payment_amount = try_tx_s!(wei_from_big_decimal( + &(args.trading_amount + args.premium_amount), + self.decimals + )); + // TODO add maker_pub created by legacy derive_htlc_pubkey support additionally? + let _maker_address = public_to_address(&Public::from_slice(args.maker_pub)); todo!() } diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 3a58b1839a..cf9358f643 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -885,7 +885,10 @@ pub enum SwapTxTypeWithSecretHash<'a> { taker_secret_hash: &'a [u8], }, /// Taker payment v2 - TakerPaymentV2 { maker_secret_hash: &'a [u8] }, + TakerPaymentV2 { + maker_secret_hash: &'a [u8], + taker_secret_hash: &'a [u8], + }, } impl<'a> SwapTxTypeWithSecretHash<'a> { @@ -907,7 +910,7 @@ impl<'a> SwapTxTypeWithSecretHash<'a> { my_public, other_public, ), - SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash } => { + SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash, .. } => { swap_proto_v2_scripts::taker_payment_script(time_lock, maker_secret_hash, my_public, other_public) }, } @@ -921,7 +924,7 @@ impl<'a> SwapTxTypeWithSecretHash<'a> { maker_secret_hash, taker_secret_hash, } => [*maker_secret_hash, *taker_secret_hash].concat(), - SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash } => maker_secret_hash.to_vec(), + SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash, .. } => maker_secret_hash.to_vec(), } } } @@ -985,6 +988,24 @@ pub struct RefundPaymentArgs<'a> { pub watcher_reward: bool, } +#[derive(Debug)] +pub struct RefundTakerPaymentArgs<'a> { + pub payment_tx: &'a [u8], + /// Needed for taker refund as for eth taker swap id `etomic_swap_v2_id` was used + pub funding_time_lock: u64, + pub time_lock: u64, + pub maker_pub: &'a [u8], + pub tx_type_with_secret_hash: SwapTxTypeWithSecretHash<'a>, + pub swap_unique_data: &'a [u8], + pub watcher_reward: bool, + /// DEX fee + pub dex_fee: &'a DexFee, + /// Additional reward for maker (premium) + pub premium_amount: BigDecimal, + /// Actual volume of taker's payment + pub trading_amount: BigDecimal, +} + /// Helper struct wrapping arguments for [SwapOps::check_if_my_payment_sent]. #[derive(Clone, Debug)] pub struct CheckIfMyPaymentSentArgs<'a> { @@ -1850,7 +1871,8 @@ pub trait TakerCoinSwapOpsV2: ParseCoinAssocTypes + Send + Sync + 'static { async fn validate_taker_funding(&self, args: ValidateTakerFundingArgs<'_, Self>) -> ValidateSwapV2TxResult; /// Refunds taker funding transaction using time-locked path without secret reveal. - async fn refund_taker_funding_timelock(&self, args: RefundPaymentArgs<'_>) -> Result; + async fn refund_taker_funding_timelock(&self, args: RefundTakerPaymentArgs<'_>) + -> Result; /// Reclaims taker funding transaction using immediate refund path with secret reveal. async fn refund_taker_funding_secret( @@ -1889,7 +1911,8 @@ pub trait TakerCoinSwapOpsV2: ParseCoinAssocTypes + Send + Sync + 'static { ) -> Result; /// Refunds taker payment transaction. - async fn refund_combined_taker_payment(&self, args: RefundPaymentArgs<'_>) -> Result; + async fn refund_combined_taker_payment(&self, args: RefundTakerPaymentArgs<'_>) + -> Result; /// Generates and signs taker payment spend preimage. The preimage and signature should be /// shared with maker to proceed with protocol execution. diff --git a/mm2src/coins/test_coin.rs b/mm2src/coins/test_coin.rs index c077bf60bd..f7e0b5d740 100644 --- a/mm2src/coins/test_coin.rs +++ b/mm2src/coins/test_coin.rs @@ -1,8 +1,8 @@ #![allow(clippy::all)] use super::{CoinBalance, FundingTxSpend, HistorySyncState, MarketCoinOps, MmCoin, RawTransactionFut, - RawTransactionRequest, SearchForFundingSpendErr, SwapOps, TradeFee, TransactionEnum, TransactionFut, - WaitForTakerPaymentSpendError}; + RawTransactionRequest, RefundTakerPaymentArgs, SearchForFundingSpendErr, SwapOps, TradeFee, + TransactionEnum, TransactionFut, WaitForTakerPaymentSpendError}; use crate::coin_errors::ValidatePaymentResult; use crate::{coin_errors::MyAddressError, BalanceFut, CanRefundHtlc, CheckIfMyPaymentSentArgs, CoinFutSpawner, ConfirmPaymentInput, FeeApproxStage, FoundSwapTxSpend, GenPreimageResult, GenTakerFundingSpendArgs, @@ -472,7 +472,10 @@ impl TakerCoinSwapOpsV2 for TestCoin { unimplemented!() } - async fn refund_taker_funding_timelock(&self, args: RefundPaymentArgs<'_>) -> Result { + async fn refund_taker_funding_timelock( + &self, + args: RefundTakerPaymentArgs<'_>, + ) -> Result { todo!() } @@ -517,7 +520,10 @@ impl TakerCoinSwapOpsV2 for TestCoin { todo!() } - async fn refund_combined_taker_payment(&self, args: RefundPaymentArgs<'_>) -> Result { + async fn refund_combined_taker_payment( + &self, + args: RefundTakerPaymentArgs<'_>, + ) -> Result { unimplemented!() } diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index 03c889d790..9763728da7 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -26,7 +26,7 @@ use crate::{CanRefundHtlc, CheckIfMyPaymentSentArgs, CoinBalance, CoinWithDeriva GenTakerPaymentSpendArgs, GetWithdrawSenderAddress, IguanaBalanceOps, IguanaPrivKey, MakerCoinSwapOpsV2, MakerSwapTakerCoin, MmCoinEnum, NegotiateSwapContractAddrErr, PaymentInstructionArgs, PaymentInstructions, PaymentInstructionsErr, PrivKeyBuildPolicy, RawTransactionRequest, RawTransactionResult, RefundError, - RefundFundingSecretArgs, RefundMakerPaymentArgs, RefundPaymentArgs, RefundResult, + RefundFundingSecretArgs, RefundMakerPaymentArgs, RefundPaymentArgs, RefundResult, RefundTakerPaymentArgs, SearchForFundingSpendErr, SearchForSwapTxSpendInput, SendMakerPaymentArgs, SendMakerPaymentSpendPreimageInput, SendPaymentArgs, SendTakerFundingArgs, SignRawTransactionRequest, SignatureResult, SpendMakerPaymentArgs, SpendPaymentArgs, SwapOps, SwapTxTypeWithSecretHash, @@ -662,7 +662,19 @@ impl TakerCoinSwapOpsV2 for UtxoStandardCoin { utxo_common::validate_taker_funding(self, args).await } - async fn refund_taker_funding_timelock(&self, args: RefundPaymentArgs<'_>) -> Result { + async fn refund_taker_funding_timelock( + &self, + args: RefundTakerPaymentArgs<'_>, + ) -> Result { + let args = RefundPaymentArgs { + payment_tx: args.payment_tx, + time_lock: args.time_lock, + other_pubkey: args.maker_pub, + tx_type_with_secret_hash: args.tx_type_with_secret_hash, + swap_contract_address: &None, + swap_unique_data: args.swap_unique_data, + watcher_reward: args.watcher_reward, + }; utxo_common::refund_htlc_payment(self.clone(), args).await } @@ -774,7 +786,19 @@ impl TakerCoinSwapOpsV2 for UtxoStandardCoin { utxo_common::sign_and_send_taker_funding_spend(self, preimage, args, &htlc_keypair).await } - async fn refund_combined_taker_payment(&self, args: RefundPaymentArgs<'_>) -> Result { + async fn refund_combined_taker_payment( + &self, + args: RefundTakerPaymentArgs<'_>, + ) -> Result { + let args = RefundPaymentArgs { + payment_tx: args.payment_tx, + time_lock: args.time_lock, + other_pubkey: args.maker_pub, + tx_type_with_secret_hash: args.tx_type_with_secret_hash, + swap_contract_address: &None, + swap_unique_data: args.swap_unique_data, + watcher_reward: args.watcher_reward, + }; utxo_common::refund_htlc_payment(self.clone(), args).await } diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs index 8591207385..5a121efc82 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs @@ -10,7 +10,7 @@ use async_trait::async_trait; use bitcrypto::{dhash160, sha256}; use coins::{CanRefundHtlc, ConfirmPaymentInput, DexFee, FeeApproxStage, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, MakerCoinSwapOpsV2, MmCoin, ParseCoinAssocTypes, RefundFundingSecretArgs, - RefundPaymentArgs, SendTakerFundingArgs, SpendMakerPaymentArgs, SwapTxTypeWithSecretHash, + RefundTakerPaymentArgs, SendTakerFundingArgs, SpendMakerPaymentArgs, SwapTxTypeWithSecretHash, TakerCoinSwapOpsV2, ToBytes, TradeFee, TradePreimageValue, Transaction, TxPreimageWithSig, ValidateMakerPaymentArgs}; use common::executor::abortable_queue::AbortableQueue; @@ -1897,18 +1897,22 @@ impl Date: Wed, 17 Jul 2024 18:12:18 +0700 Subject: [PATCH 093/233] change sleep Duration --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 7ea72c73b7..e032aef986 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -838,7 +838,7 @@ fn send_and_refund_erc20_maker_payment_priority_fee() { } fn send_and_spend_erc20_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { - thread::sleep(Duration::from_secs(7)); + thread::sleep(Duration::from_secs(5)); let maker_erc20_coin = erc20_coin_with_random_privkey(swap_contract()); let taker_erc20_coin = erc20_coin_with_random_privkey(swap_contract()); @@ -1074,7 +1074,7 @@ fn test_nonce_lock() { #[test] fn send_and_refund_erc721_maker_payment_timelock() { - thread::sleep(Duration::from_secs(33)); + thread::sleep(Duration::from_secs(29)); let token_id = 2u32; let time_lock_to_refund = now_sec() - 1000; let activation = NftActivationV2Args::init(); From ae16a3c499d973088c22a1c7807393d6fbeb60bc Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 17 Jul 2024 19:30:14 +0700 Subject: [PATCH 094/233] eth tpu v2: refund_taker_funding_timelock_impl --- mm2src/coins/eth/eth_swap_v2.rs | 94 ++++++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 6 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 63d126e771..bc10045818 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,6 +1,6 @@ use super::eth::{gas_limit, wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; use super::{RefundFundingSecretArgs, SendTakerFundingArgs, Transaction, TransactionErr}; -use crate::RefundTakerPaymentArgs; +use crate::{RefundTakerPaymentArgs, SwapTxTypeWithSecretHash}; use enum_derives::EnumFromStringify; use ethabi::Token; use ethcore_transaction::Action; @@ -29,6 +29,17 @@ struct TakerRefundSecretArgs<'a> { payment_time_lock: u32, } +struct TakerRefundArgs<'a> { + dex_fee: U256, + payment_amount: U256, + maker_address: Address, + taker_secret_hash: &'a [u8], + maker_secret_hash: &'a [u8], + funding_time_lock: u32, + payment_time_lock: u32, + token_address: Address, +} + impl EthCoin { pub(crate) async fn send_taker_funding_impl( &self, @@ -128,22 +139,67 @@ impl EthCoin { &self, args: RefundTakerPaymentArgs<'_>, ) -> Result { - let _taker_swap_v2_contract = self + let taker_swap_v2_contract = self .swap_v2_contracts .as_ref() .map(|contracts| contracts.taker_swap_v2_contract) .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; - let _dex_fee = try_tx_s!(wei_from_big_decimal( + let dex_fee = try_tx_s!(wei_from_big_decimal( &args.dex_fee.fee_amount().to_decimal(), self.decimals )); - let _payment_amount = try_tx_s!(wei_from_big_decimal( + let payment_amount = try_tx_s!(wei_from_big_decimal( &(args.trading_amount + args.premium_amount), self.decimals )); // TODO add maker_pub created by legacy derive_htlc_pubkey support additionally? - let _maker_address = public_to_address(&Public::from_slice(args.maker_pub)); - todo!() + let maker_address = public_to_address(&Public::from_slice(args.maker_pub)); + let funding_time_lock: u32 = try_tx_s!(args.funding_time_lock.try_into()); + let payment_time_lock: u32 = try_tx_s!(args.time_lock.try_into()); + let (maker_secret_hash, taker_secret_hash) = match args.tx_type_with_secret_hash { + SwapTxTypeWithSecretHash::TakerPaymentV2 { + maker_secret_hash, + taker_secret_hash, + } => (maker_secret_hash, taker_secret_hash), + _ => { + return Err(TransactionErr::Plain(ERRL!( + "Unsupported swap tx type for timelock refund" + ))) + }, + }; + + let (token_address, gas_limit) = match &self.coin_type { + EthCoinType::Eth => (Address::default(), gas_limit::ETH_SENDER_REFUND), + EthCoinType::Erc20 { + platform: _, + token_addr, + } => (*token_addr, gas_limit::ERC20_SENDER_REFUND), + EthCoinType::Nft { .. } => { + return Err(TransactionErr::ProtocolNotSupported( + "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), + )) + }, + }; + let args = TakerRefundArgs { + dex_fee, + payment_amount, + maker_address, + taker_secret_hash, + maker_secret_hash, + funding_time_lock, + payment_time_lock, + token_address, + }; + let data = try_tx_s!(self.prepare_taker_refund_payment_timelock_data(args).await); + + self.sign_and_send_transaction( + payment_amount, + Action::Call(taker_swap_v2_contract), + data, + U256::from(gas_limit), + ) + .compat() + .await } pub(crate) async fn refund_taker_funding_secret_impl( @@ -269,6 +325,32 @@ impl EthCoin { Ok(data) } + /// Prepares data for EtomicSwapTakerV2 contract `refundTakerPaymentTimelock` method + /// function refundMakerPaymentTimelock( + /// bytes32 id, + /// uint256 amount, + /// address taker, + /// bytes32 takerSecretHash, + /// bytes32 makerSecretHash, + /// address tokenAddress + async fn prepare_taker_refund_payment_timelock_data( + &self, + args: TakerRefundArgs<'_>, + ) -> Result, PrepareTxDataError> { + let function = TAKER_SWAP_V2.function("refundTakerPaymentTimelock")?; + let id = self.etomic_swap_v2_id(args.funding_time_lock, args.payment_time_lock, args.taker_secret_hash); + let data = function.encode_input(&[ + Token::FixedBytes(id), + Token::Uint(args.payment_amount), + Token::Uint(args.dex_fee), + Token::Address(args.maker_address), + Token::FixedBytes(args.taker_secret_hash.to_vec()), + Token::FixedBytes(args.maker_secret_hash.to_vec()), + Token::Address(args.token_address), + ])?; + Ok(data) + } + /// Prepares data for EtomicSwapTakerV2 contract `refundTakerPaymentSecret` method /// function refundTakerPaymentSecret( /// bytes32 id, From 01cd625293030781632f18d8a5231548b743f409 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 17 Jul 2024 19:43:25 +0700 Subject: [PATCH 095/233] eth tpu v2: refactor refund_taker_funding_secret_impl --- mm2src/coins/eth/eth_swap_v2.rs | 63 +++++++++++++-------------------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index bc10045818..e86bff2062 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -27,6 +27,7 @@ struct TakerRefundSecretArgs<'a> { maker_secret_hash: &'a [u8], funding_time_lock: u32, payment_time_lock: u32, + token_address: Address, } struct TakerRefundArgs<'a> { @@ -222,6 +223,18 @@ impl EthCoin { let maker_address = public_to_address(args.maker_pubkey); let funding_time_lock: u32 = try_tx_s!(args.funding_time_lock.try_into()); let payment_time_lock: u32 = try_tx_s!(args.payment_time_lock.try_into()); + let (token_address, gas_limit) = match &self.coin_type { + EthCoinType::Eth => (Address::default(), gas_limit::ETH_SENDER_REFUND), + EthCoinType::Erc20 { + platform: _, + token_addr, + } => (*token_addr, gas_limit::ERC20_SENDER_REFUND), + EthCoinType::Nft { .. } => { + return Err(TransactionErr::ProtocolNotSupported( + "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), + )) + }, + }; let refund_args = TakerRefundSecretArgs { dex_fee, payment_amount, @@ -230,43 +243,18 @@ impl EthCoin { maker_secret_hash: args.maker_secret_hash, funding_time_lock, payment_time_lock, + token_address, }; - match &self.coin_type { - EthCoinType::Eth => { - let data = try_tx_s!( - self.prepare_taker_refund_payment_secret_data(&refund_args, Address::default()) - .await - ); - self.sign_and_send_transaction( - payment_amount, - Action::Call(taker_swap_v2_contract), - data, - U256::from(gas_limit::ETH_SENDER_REFUND), - ) - .compat() - .await - }, - EthCoinType::Erc20 { - platform: _, - token_addr, - } => { - let data = try_tx_s!( - self.prepare_taker_refund_payment_secret_data(&refund_args, *token_addr) - .await - ); - self.sign_and_send_transaction( - payment_amount, - Action::Call(taker_swap_v2_contract), - data, - U256::from(gas_limit::ERC20_SENDER_REFUND), - ) - .compat() - .await - }, - EthCoinType::Nft { .. } => Err(TransactionErr::ProtocolNotSupported( - "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), - )), - } + let data = try_tx_s!(self.prepare_taker_refund_payment_secret_data(&refund_args).await); + + self.sign_and_send_transaction( + payment_amount, + Action::Call(taker_swap_v2_contract), + data, + U256::from(gas_limit), + ) + .compat() + .await } /// Prepares data for EtomicSwapTakerV2 contract `ethTakerPayment` method @@ -363,7 +351,6 @@ impl EthCoin { async fn prepare_taker_refund_payment_secret_data( &self, args: &TakerRefundSecretArgs<'_>, - token_address: Address, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("refundTakerPaymentSecret")?; let id = self.etomic_swap_v2_id(args.funding_time_lock, args.payment_time_lock, args.taker_secret); @@ -374,7 +361,7 @@ impl EthCoin { Token::Address(args.maker_address), Token::FixedBytes(args.taker_secret.to_vec()), Token::FixedBytes(args.maker_secret_hash.to_vec()), - Token::Address(token_address), + Token::Address(args.token_address), ])?; Ok(data) } From 7b698869f98f113f48e75e78d84a0cd12a4d05e9 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 18 Jul 2024 11:49:33 +0700 Subject: [PATCH 096/233] fmt and clippy --- mm2src/coins/eth/nft_swap_v2/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index a21bcc7210..3245f3b434 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -15,8 +15,8 @@ mod structs; use structs::{ExpectedHtlcParams, PaymentType, ValidationParams}; use super::ContractType; -use crate::eth::{decode_contract_call, EthCoin, EthCoinType, MakerPaymentStateV2, - SignedEthTx, ERC1155_CONTRACT, ERC721_CONTRACT, NFT_MAKER_SWAP_V2}; +use crate::eth::{decode_contract_call, EthCoin, EthCoinType, MakerPaymentStateV2, SignedEthTx, ERC1155_CONTRACT, + ERC721_CONTRACT, NFT_MAKER_SWAP_V2}; use crate::{ParseCoinAssocTypes, RefundNftMakerPaymentArgs, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, TransactionErr, ValidateNftMakerPaymentArgs}; @@ -159,7 +159,7 @@ impl EthCoin { 0.into(), Action::Call(*etomic_swap_contract), data, - U256::from(ETH_MAX_TRADE_GAS), // TODO: fix to a more accurate const or estimated value + U256::from(self.gas_limit.eth_max_trade_gas), // TODO: fix to a more accurate const or estimated value ) .compat() .await @@ -238,7 +238,7 @@ impl EthCoin { 0.into(), Action::Call(*etomic_swap_contract), data, - U256::from(ETH_MAX_TRADE_GAS), // TODO: fix to a more accurate const or estimated value + U256::from(self.gas_limit.eth_max_trade_gas), // TODO: fix to a more accurate const or estimated value ) .compat() .await From 603daa76467034d48c6e77bc8d7f8ee8362a2c88 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 18 Jul 2024 12:13:17 +0700 Subject: [PATCH 097/233] use `self.gas_limit` instead of `mod gas_limit` in eth_swap_v2.rs --- mm2src/coins/eth/eth_swap_v2.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index e86bff2062..9c5c1f4de4 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,4 +1,4 @@ -use super::eth::{gas_limit, wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; +use super::eth::{wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; use super::{RefundFundingSecretArgs, SendTakerFundingArgs, Transaction, TransactionErr}; use crate::{RefundTakerPaymentArgs, SwapTxTypeWithSecretHash}; use enum_derives::EnumFromStringify; @@ -80,7 +80,7 @@ impl EthCoin { payment_amount, Action::Call(taker_swap_v2_contract), data, - U256::from(gas_limit::ETH_PAYMENT), + U256::from(self.gas_limit.eth_payment), ) .compat() .await @@ -115,7 +115,7 @@ impl EthCoin { U256::from(0), Action::Call(taker_swap_v2_contract), data, - U256::from(gas_limit::ERC20_PAYMENT), + U256::from(self.gas_limit.erc20_payment), ) .compat() .await @@ -124,7 +124,7 @@ impl EthCoin { U256::from(0), Action::Call(taker_swap_v2_contract), data, - U256::from(gas_limit::ERC20_PAYMENT), + U256::from(self.gas_limit.erc20_payment), ) .compat() .await @@ -170,11 +170,11 @@ impl EthCoin { }; let (token_address, gas_limit) = match &self.coin_type { - EthCoinType::Eth => (Address::default(), gas_limit::ETH_SENDER_REFUND), + EthCoinType::Eth => (Address::default(), self.gas_limit.eth_sender_refund), EthCoinType::Erc20 { platform: _, token_addr, - } => (*token_addr, gas_limit::ERC20_SENDER_REFUND), + } => (*token_addr, self.gas_limit.erc20_sender_refund), EthCoinType::Nft { .. } => { return Err(TransactionErr::ProtocolNotSupported( "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), @@ -224,11 +224,11 @@ impl EthCoin { let funding_time_lock: u32 = try_tx_s!(args.funding_time_lock.try_into()); let payment_time_lock: u32 = try_tx_s!(args.payment_time_lock.try_into()); let (token_address, gas_limit) = match &self.coin_type { - EthCoinType::Eth => (Address::default(), gas_limit::ETH_SENDER_REFUND), + EthCoinType::Eth => (Address::default(), self.gas_limit.eth_sender_refund), EthCoinType::Erc20 { platform: _, token_addr, - } => (*token_addr, gas_limit::ERC20_SENDER_REFUND), + } => (*token_addr, self.gas_limit.erc20_sender_refund), EthCoinType::Nft { .. } => { return Err(TransactionErr::ProtocolNotSupported( "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), From 99ec5221e859abaabc1fb6d181e56bfaf56c2275 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 18 Jul 2024 12:24:14 +0700 Subject: [PATCH 098/233] use EthGasLimit::default() in EthCoin set_coin_type --- mm2src/coins/eth.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 0d6c489cb4..b3c222f0b4 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7260,6 +7260,7 @@ impl EthCoin { erc20_tokens_infos: Arc::clone(&self.erc20_tokens_infos), nfts_infos: Arc::clone(&self.nfts_infos), platform_fee_estimator_state: Arc::clone(&self.platform_fee_estimator_state), + gas_limit: EthGasLimit::default(), abortable_system: self.abortable_system.create_subsystem().unwrap(), }; EthCoin(Arc::new(coin)) From dab5bd996fe5620623aac5b2f3cd4016c3c27a20 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 19 Jul 2024 16:13:41 +0700 Subject: [PATCH 099/233] fmt, clippy --- mm2src/coins/eth.rs | 1 - .../tests/docker_tests/docker_tests_common.rs | 1 - .../tests/docker_tests/eth_docker_tests.rs | 23 ++++--------------- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index b3f778dda9..b6e10c21c6 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -173,7 +173,6 @@ const ERC721_ABI: &str = include_str!("eth/erc721_abi.json"); const ERC1155_ABI: &str = include_str!("eth/erc1155_abi.json"); const NFT_SWAP_CONTRACT_ABI: &str = include_str!("eth/nft_swap_contract_abi.json"); const NFT_MAKER_SWAP_V2_ABI: &str = include_str!("eth/nft_maker_swap_v2_abi.json"); -const NFT_MAKER_SWAP_V2_ABI: &str = include_str!("eth/nft_maker_swap_v2_abi.json"); const MAKER_SWAP_V2_ABI: &str = include_str!("eth/maker_swap_v2_abi.json"); const TAKER_SWAP_V2_ABI: &str = include_str!("eth/taker_swap_v2_abi.json"); diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 7e3521eceb..bcb91da517 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -143,7 +143,6 @@ pub const NFT_MAKER_SWAP_V2_BYTES: &str = pub const MAKER_SWAP_V2_BYTES: &str = include_str!("../../../mm2_test_helpers/contract_bytes/maker_swap_v2_bytes"); /// https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapTakerV2.sol pub const TAKER_SWAP_V2_BYTES: &str = include_str!("../../../mm2_test_helpers/contract_bytes/taker_swap_v2_bytes"); -pub const NFT_MAKER_SWAP_V2_BYTES: &str = "6080604052348015600e575f80fd5b50612ffd8061001c5f395ff3fe608060405234801561000f575f80fd5b50600436106100a7575f3560e01c8063b27e46fb1161006f578063b27e46fb1461015f578063bc197c811461017b578063c8d9009b146101ab578063c92cd12d146101c7578063efccb9eb146101e3578063f23a6e6114610215576100a7565b806301ffc9a7146100ab57806305ec158d146100db5780630f235fce146100f7578063150b7a02146101135780636e6bf6d214610143575b5f80fd5b6100c560048036038101906100c09190611ebc565b610245565b6040516100d29190611f01565b60405180910390f35b6100f560048036038101906100f09190611fda565b610326565b005b610111600480360381019061010c9190612077565b6105e6565b005b61012d60048036038101906101289190612161565b6108a0565b60405161013a91906121f4565b60405180910390f35b61015d60048036038101906101589190612077565b610cef565b005b61017960048036038101906101749190611fda565b610faa565b005b61019560048036038101906101909190612262565b611269565b6040516101a291906121f4565b60405180910390f35b6101c560048036038101906101c09190612077565b6112a5565b005b6101e160048036038101906101dc9190611fda565b6115ce565b005b6101fd60048036038101906101f89190612339565b6118fc565b60405161020c9392919061242f565b60405180910390f35b61022f600480360381019061022a9190612464565b611948565b60405161023c91906121f4565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061030f57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061031f575061031e82611ddc565b5b9050919050565b6001600381111561033a576103396123bc565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561036c5761036b6123bc565b5b146103ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a39061257a565b60405180910390fd5b5f600387336002896040516020016103c491906125b8565b6040516020818303038152906040526040516103e09190612624565b602060405180830381855afa1580156103fb573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061041e919061264e565b8888888860405160200161043897969594939291906126de565b6040516020818303038152906040526040516104549190612624565b602060405180830381855afa15801561046f573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146104f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f0906127a8565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561052f5761052e6123bc565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd738860405161056391906127d5565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016105ae949392919061283f565b5f604051808303815f87803b1580156105c5575f80fd5b505af11580156105d7573d5f803e3d5ffd5b50505050505050505050505050565b600160038111156105fa576105f96123bc565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561062c5761062b6123bc565b5b1461066c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106639061257a565b60405180910390fd5b5f600386338787878760405160200161068a96959493929190612895565b6040516020818303038152906040526040516106a69190612624565b602060405180830381855afa1580156106c1573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461074b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610742906127a8565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156107b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ad90612974565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff021916908360038111156107ec576107eb6123bc565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad192190728760405161082091906127d5565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b815260040161086993929190612992565b5f604051808303815f87803b158015610880575f80fd5b505af1158015610892573d5f803e3d5ffd5b505050505050505050505050565b5f8083838101906108b19190612b1a565b90505f60038111156108c6576108c56123bc565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff1660038111156108fb576108fa6123bc565b5b1461093b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093290612bb5565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff16036109ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109a490612c1d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610a1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1690612c85565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8890612d13565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610aff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af690612d7b565b60405180910390fd5b610b0c8160200151611e45565b15610b4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4390612de3565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610b7a96959493929190612895565b604051602081830303815290604052604051610b969190612624565b602060405180830381855afa158015610bb1573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115610c0157610c006123bc565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115610c9857610c976123bc565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051610cd291906127d5565b60405180910390a163150b7a0260e01b9250505095945050505050565b60016003811115610d0357610d026123bc565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff166003811115610d3557610d346123bc565b5b14610d75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6c9061257a565b60405180910390fd5b5f60038633600288604051602001610d8d91906125b8565b604051602081830303815290604052604051610da99190612624565b602060405180830381855afa158015610dc4573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610de7919061264e565b878787604051602001610dff96959493929190612895565b604051602081830303815290604052604051610e1b9190612624565b602060405180830381855afa158015610e36573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610ec0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb7906127a8565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610ef657610ef56123bc565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051610f2a91906127d5565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610f7393929190612992565b5f604051808303815f87803b158015610f8a575f80fd5b505af1158015610f9c573d5f803e3d5ffd5b505050505050505050505050565b60016003811115610fbe57610fbd6123bc565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115610ff057610fef6123bc565b5b14611030576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110279061257a565b60405180910390fd5b5f60038733888888888860405160200161105097969594939291906126de565b60405160208183030381529060405260405161106c9190612624565b602060405180830381855afa158015611087573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611111576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611108906127a8565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff1642101561117c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117390612974565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156111b2576111b16123bc565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad19219072886040516111e691906127d5565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b8152600401611231949392919061283f565b5f604051808303815f87803b158015611248575f80fd5b505af115801561125a573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129c90612e4b565b60405180910390fd5b600160038111156112b9576112b86123bc565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff1660038111156112eb576112ea6123bc565b5b1461132b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113229061257a565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139090612eb3565b60405180910390fd5b5f60033387876002886040516020016113b291906125b8565b6040516020818303038152906040526040516113ce9190612624565b602060405180830381855afa1580156113e9573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061140c919061264e565b878760405160200161142396959493929190612895565b60405160208183030381529060405260405161143f9190612624565b602060405180830381855afa15801561145a573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146114e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114db906127a8565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561151a576115196123bc565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161154e91906127d5565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b815260040161159793929190612992565b5f604051808303815f87803b1580156115ae575f80fd5b505af11580156115c0573d5f803e3d5ffd5b505050505050505050505050565b600160038111156115e2576115e16123bc565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115611614576116136123bc565b5b14611654576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164b9061257a565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b990612eb3565b60405180910390fd5b5f60033388886002896040516020016116db91906125b8565b6040516020818303038152906040526040516116f79190612624565b602060405180830381855afa158015611712573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190611735919061264e565b88888860405160200161174e97969594939291906126de565b60405160208183030381529060405260405161176a9190612624565b602060405180830381855afa158015611785573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461180f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611806906127a8565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff02191690836003811115611845576118446123bc565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08860405161187991906127d5565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016118c4949392919061283f565b5f604051808303815f87803b1580156118db575f80fd5b505af11580156118ed573d5f803e3d5ffd5b50505050505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f8083838101906119599190612b1a565b90505f600381111561196e5761196d6123bc565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff1660038111156119a3576119a26123bc565b5b146119e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119da90612f41565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603611a55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4c90612c1d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603611ac7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611abe90612c85565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611b39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3090612d13565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614611ba7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9e90612d7b565b60405180910390fd5b5f8511611be9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be090612fa9565b60405180910390fd5b611bf68160200151611e45565b15611c36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2d90612de3565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c604051602001611c6697969594939291906126de565b604051602081830303815290604052604051611c829190612624565b602060405180830381855afa158015611c9d573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff16815260200160016003811115611ced57611cec6123bc565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115611d8457611d836123bc565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f0151604051611dbe91906127d5565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611e9b81611e67565b8114611ea5575f80fd5b50565b5f81359050611eb681611e92565b92915050565b5f60208284031215611ed157611ed0611e5f565b5b5f611ede84828501611ea8565b91505092915050565b5f8115159050919050565b611efb81611ee7565b82525050565b5f602082019050611f145f830184611ef2565b92915050565b5f819050919050565b611f2c81611f1a565b8114611f36575f80fd5b50565b5f81359050611f4781611f23565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611f7682611f4d565b9050919050565b611f8681611f6c565b8114611f90575f80fd5b50565b5f81359050611fa181611f7d565b92915050565b5f819050919050565b611fb981611fa7565b8114611fc3575f80fd5b50565b5f81359050611fd481611fb0565b92915050565b5f805f805f805f60e0888a031215611ff557611ff4611e5f565b5b5f6120028a828b01611f39565b97505060206120138a828b01611f93565b96505060406120248a828b01611f39565b95505060606120358a828b01611f39565b94505060806120468a828b01611f93565b93505060a06120578a828b01611fc6565b92505060c06120688a828b01611fc6565b91505092959891949750929550565b5f805f805f8060c0878903121561209157612090611e5f565b5b5f61209e89828a01611f39565b96505060206120af89828a01611f93565b95505060406120c089828a01611f39565b94505060606120d189828a01611f39565b93505060806120e289828a01611f93565b92505060a06120f389828a01611fc6565b9150509295509295509295565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261212157612120612100565b5b8235905067ffffffffffffffff81111561213e5761213d612104565b5b60208301915083600182028301111561215a57612159612108565b5b9250929050565b5f805f805f6080868803121561217a57612179611e5f565b5b5f61218788828901611f93565b955050602061219888828901611f93565b94505060406121a988828901611fc6565b935050606086013567ffffffffffffffff8111156121ca576121c9611e63565b5b6121d68882890161210c565b92509250509295509295909350565b6121ee81611e67565b82525050565b5f6020820190506122075f8301846121e5565b92915050565b5f8083601f84011261222257612221612100565b5b8235905067ffffffffffffffff81111561223f5761223e612104565b5b60208301915083602082028301111561225b5761225a612108565b5b9250929050565b5f805f805f805f8060a0898b03121561227e5761227d611e5f565b5b5f61228b8b828c01611f93565b985050602061229c8b828c01611f93565b975050604089013567ffffffffffffffff8111156122bd576122bc611e63565b5b6122c98b828c0161220d565b9650965050606089013567ffffffffffffffff8111156122ec576122eb611e63565b5b6122f88b828c0161220d565b9450945050608089013567ffffffffffffffff81111561231b5761231a611e63565b5b6123278b828c0161210c565b92509250509295985092959890939650565b5f6020828403121561234e5761234d611e5f565b5b5f61235b84828501611f39565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b61239881612364565b82525050565b5f63ffffffff82169050919050565b6123b68161239e565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600481106123fa576123f96123bc565b5b50565b5f81905061240a826123e9565b919050565b5f612419826123fd565b9050919050565b6124298161240f565b82525050565b5f6060820190506124425f83018661238f565b61244f60208301856123ad565b61245c6040830184612420565b949350505050565b5f805f805f8060a0878903121561247e5761247d611e5f565b5b5f61248b89828a01611f93565b965050602061249c89828a01611f93565b95505060406124ad89828a01611fc6565b94505060606124be89828a01611fc6565b935050608087013567ffffffffffffffff8111156124df576124de611e63565b5b6124eb89828a0161210c565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f612564602a836124fa565b915061256f8261250a565b604082019050919050565b5f6020820190508181035f83015261259181612558565b9050919050565b5f819050919050565b6125b26125ad82611f1a565b612598565b82525050565b5f6125c382846125a1565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6125fe826125d2565b61260881856125dc565b93506126188185602086016125e6565b80840191505092915050565b5f61262f82846125f4565b915081905092915050565b5f8151905061264881611f23565b92915050565b5f6020828403121561266357612662611e5f565b5b5f6126708482850161263a565b91505092915050565b5f8160601b9050919050565b5f61268f82612679565b9050919050565b5f6126a082612685565b9050919050565b6126b86126b382611f6c565b612696565b82525050565b5f819050919050565b6126d86126d382611fa7565b6126be565b82525050565b5f6126e9828a6126a7565b6014820191506126f982896126a7565b60148201915061270982886125a1565b60208201915061271982876125a1565b60208201915061272982866126a7565b60148201915061273982856126c7565b60208201915061274982846126c7565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f6127926013836124fa565b915061279d8261275e565b602082019050919050565b5f6020820190508181035f8301526127bf81612786565b9050919050565b6127cf81611f1a565b82525050565b5f6020820190506127e85f8301846127c6565b92915050565b6127f781611f6c565b82525050565b61280681611fa7565b82525050565b5f82825260208201905092915050565b50565b5f61282a5f8361280c565b91506128358261281c565b5f82019050919050565b5f60a0820190506128525f8301876127ee565b61285f60208301866127ee565b61286c60408301856127fd565b61287960608301846127fd565b818103608083015261288a8161281f565b905095945050505050565b5f6128a082896126a7565b6014820191506128b082886126a7565b6014820191506128c082876125a1565b6020820191506128d082866125a1565b6020820191506128e082856126a7565b6014820191506128f082846126c7565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f61295e6038836124fa565b915061296982612904565b604082019050919050565b5f6020820190508181035f83015261298b81612952565b9050919050565b5f6060820190506129a55f8301866127ee565b6129b260208301856127ee565b6129bf60408301846127fd565b949350505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612a11826129cb565b810181811067ffffffffffffffff82111715612a3057612a2f6129db565b5b80604052505050565b5f612a42611e56565b9050612a4e8282612a08565b919050565b612a5c8161239e565b8114612a66575f80fd5b50565b5f81359050612a7781612a53565b92915050565b5f60c08284031215612a9257612a916129c7565b5b612a9c60c0612a39565b90505f612aab84828501611f39565b5f830152506020612abe84828501611f93565b6020830152506040612ad284828501611f93565b6040830152506060612ae684828501611f39565b6060830152506080612afa84828501611f39565b60808301525060a0612b0e84828501612a69565b60a08301525092915050565b5f60c08284031215612b2f57612b2e611e5f565b5b5f612b3c84828501612a7d565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f612b9f602a836124fa565b9150612baa82612b45565b604082019050919050565b5f6020820190508181035f830152612bcc81612b93565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612c07601e836124fa565b9150612c1282612bd3565b602082019050919050565b5f6020820190508181035f830152612c3481612bfb565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f612c6f601e836124fa565b9150612c7a82612c3b565b602082019050919050565b5f6020820190508181035f830152612c9c81612c63565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f612cfd6023836124fa565b9150612d0882612ca3565b604082019050919050565b5f6020820190508181035f830152612d2a81612cf1565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f612d65601b836124fa565b9150612d7082612d31565b602082019050919050565b5f6020820190508181035f830152612d9281612d59565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f612dcd601a836124fa565b9150612dd882612d99565b602082019050919050565b5f6020820190508181035f830152612dfa81612dc1565b9050919050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f612e35601d836124fa565b9150612e4082612e01565b602082019050919050565b5f6020820190508181035f830152612e6281612e29565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f612e9d6015836124fa565b9150612ea882612e69565b602082019050919050565b5f6020820190508181035f830152612eca81612e91565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f612f2b602b836124fa565b9150612f3682612ed1565b604082019050919050565b5f6020820190508181035f830152612f5881612f1f565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f612f93601c836124fa565b9150612f9e82612f5f565b602082019050919050565b5f6020820190508181035f830152612fc081612f87565b905091905056fea26469706673582212204e239c256ffaf5624f6d55ae2e9f8afd626e0e129a36ff33221d4b2fe58f6b5a64736f6c63430008190033"; pub trait CoinDockerOps { fn rpc_client(&self) -> &UtxoRpcClientEnum; diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 2cbc027c63..7d392521cc 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1,9 +1,9 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC721_TEST_ABI, GETH_ACCOUNT, - GETH_ERC1155_CONTRACT, GETH_ERC20_CONTRACT, GETH_ERC721_CONTRACT, + GETH_ERC1155_CONTRACT, GETH_ERC20_CONTRACT, GETH_ERC721_CONTRACT, GETH_MAKER_SWAP_V2, GETH_NFT_MAKER_SWAP_V2, GETH_NFT_SWAP_CONTRACT, GETH_NONCE_LOCK, GETH_RPC_URL, - GETH_SWAP_CONTRACT, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, MM_CTX, MM_CTX1,GETH_MAKER_SWAP_V2, - SEPOLIA_ERC1155_CONTRACT,GETH_TAKER_SWAP_V2, SEPOLIA_ERC721_CONTRACT, SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2, - SEPOLIA_NONCE_LOCK, SEPOLIA_RPC_URL, SEPOLIA_WEB3}; + GETH_SWAP_CONTRACT, GETH_TAKER_SWAP_V2, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, + MM_CTX, SEPOLIA_ERC1155_CONTRACT, SEPOLIA_ERC721_CONTRACT, + SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2, SEPOLIA_NONCE_LOCK, SEPOLIA_RPC_URL, SEPOLIA_WEB3}; use crate::common::Future01CompatExt; use bitcrypto::{dhash160, sha256}; use coins::eth::gas_limit::ETH_MAX_TRADE_GAS; @@ -111,21 +111,6 @@ pub fn sepolia_erc721() -> Address { unsafe { SEPOLIA_ERC721_CONTRACT } } /// SEPOLIA_ERC1155_CONTRACT address is set once during initialization before tests start pub fn sepolia_erc1155() -> Address { unsafe { SEPOLIA_ERC1155_CONTRACT } } -/// # Safety -/// -/// SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2 address is set once during initialization before tests start -pub fn sepolia_etomic_maker_nft() -> Address { unsafe { SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2 } } - -/// # Safety -/// -/// SEPOLIA_ERC721_CONTRACT address is set once during initialization before tests start -pub fn sepolia_erc721() -> Address { unsafe { SEPOLIA_ERC721_CONTRACT } } - -/// # Safety -/// -/// SEPOLIA_ERC1155_CONTRACT address is set once during initialization before tests start -pub fn sepolia_erc1155() -> Address { unsafe { SEPOLIA_ERC1155_CONTRACT } } - fn wait_for_confirmation(tx_hash: H256) { thread::sleep(Duration::from_millis(2000)); loop { From 42f6d379281f84d426074a011cb7666fd95c315a Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 19 Jul 2024 14:08:05 +0700 Subject: [PATCH 100/233] test send_and_refund_taker_funding_timelock_eth WIP --- mm2src/coins/eth/eth_swap_v2.rs | 4 +- .../tests/docker_tests/eth_docker_tests.rs | 55 +++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 9c5c1f4de4..0981ebce3b 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,6 +1,6 @@ use super::eth::{wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; -use super::{RefundFundingSecretArgs, SendTakerFundingArgs, Transaction, TransactionErr}; -use crate::{RefundTakerPaymentArgs, SwapTxTypeWithSecretHash}; +use super::{RefundFundingSecretArgs, RefundTakerPaymentArgs, SendTakerFundingArgs, SwapTxTypeWithSecretHash, + Transaction, TransactionErr}; use enum_derives::EnumFromStringify; use ethabi::Token; use ethcore_transaction::Action; diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index e032aef986..e7bc146fe8 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1624,3 +1624,58 @@ fn send_and_refund_taker_funding_by_secret_erc20() { funding_tx_refund.tx_hash() ); } + +#[ignore] +#[test] +fn send_and_refund_taker_funding_timelock_eth() { + let taker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init()); + let maker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init()); + + let taker_secret = vec![0; 32]; + let taker_secret_hash = sha256(&taker_secret).to_vec(); + let maker_secret = vec![1; 32]; + let maker_secret_hash = sha256(&maker_secret).to_vec(); + // TODO exceed funding_time_lock, as if TakerPaymentState.PaymentSent then + // timestamp should exceed payment pre-approve lock time + let funding_time_lock = now_sec() + 3000; + let payment_time_lock = now_sec() + 1000; + + let dex_fee = &DexFee::Standard("0.1".into()); + let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); + let payment_args = SendTakerFundingArgs { + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + maker_pub: maker_pub.as_bytes(), + dex_fee, + premium_amount: BigDecimal::default(), + trading_amount: 1.into(), + swap_unique_data: &[], + wait_for_confirmation_until: 0, + }; + let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); + log!("Taker sent ETH Funding, tx hash: {:02x}", funding_tx.tx_hash()); + + wait_for_confirmations(&taker_coin, &funding_tx, 60); + + let refund_args = RefundFundingSecretArgs { + funding_tx: &funding_tx, + funding_time_lock, + payment_time_lock, + maker_pubkey: &taker_coin.derive_htlc_pubkey_v2(&[]), + taker_secret: &taker_secret, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + dex_fee, + premium_amount: Default::default(), + trading_amount: 1.into(), + swap_unique_data: &[], + watcher_reward: false, + }; + let funding_tx_refund = block_on(taker_coin.refund_taker_funding_secret(refund_args)).unwrap(); + log!( + "Taker refunded ETH Funding by Secret, tx hash: {:02x}", + funding_tx_refund.tx_hash() + ); +} From 114637ad25deb9270320e683f6f8cf62a77c8170 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 19 Jul 2024 17:46:27 +0700 Subject: [PATCH 101/233] eth tpu v2: test send_and_refund_taker_funding_timelock_eth --- mm2src/coins/eth.rs | 1 + .../tests/docker_tests/eth_docker_tests.rs | 52 ++++++++++--------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index b3c222f0b4..dc08b85f4d 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7161,6 +7161,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { todo!() } + // TODO lets call refund_taker_funding_timelock inside this func? async fn refund_combined_taker_payment( &self, _args: RefundTakerPaymentArgs<'_>, diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index deaf6d71d6..f0dd0bd18d 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -14,10 +14,10 @@ use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, ConfirmPaymentInput, DerivationMethod, DexFee, Eip1559Ops, FoundSwapTxSpend, MakerNftSwapOpsV2, MarketCoinOps, MmCoinEnum, MmCoinStruct, NftSwapInfo, ParseCoinAssocTypes, ParseNftAssocTypes, PrivKeyBuildPolicy, RefundFundingSecretArgs, - RefundNftMakerPaymentArgs, RefundPaymentArgs, SearchForSwapTxSpendInput, SendNftMakerPaymentArgs, - SendPaymentArgs, SendTakerFundingArgs, SpendNftMakerPaymentArgs, SpendPaymentArgs, SwapOps, - SwapTxFeePolicy, SwapTxTypeWithSecretHash, TakerCoinSwapOpsV2, ToBytes, Transaction, - ValidateNftMakerPaymentArgs}; + RefundNftMakerPaymentArgs, RefundPaymentArgs, RefundTakerPaymentArgs, SearchForSwapTxSpendInput, + SendNftMakerPaymentArgs, SendPaymentArgs, SendTakerFundingArgs, SpendNftMakerPaymentArgs, + SpendPaymentArgs, SwapOps, SwapTxFeePolicy, SwapTxTypeWithSecretHash, TakerCoinSwapOpsV2, ToBytes, + Transaction, ValidateNftMakerPaymentArgs}; use common::{block_on, now_sec}; use crypto::Secp256k1Secret; use ethcore_transaction::Action; @@ -1548,7 +1548,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { wait_for_confirmation_until: 0, }; let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); - log!("Taker sent ETH Funding, tx hash: {:02x}", funding_tx.tx_hash()); + log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); wait_for_confirmations(&taker_coin, &funding_tx, 60); @@ -1568,7 +1568,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { }; let funding_tx_refund = block_on(taker_coin.refund_taker_funding_secret(refund_args)).unwrap(); log!( - "Taker refunded ETH Funding by Secret, tx hash: {:02x}", + "Taker refunded ETH funding by secret, tx hash: {:02x}", funding_tx_refund.tx_hash() ); } @@ -1602,7 +1602,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { }; let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); - log!("Taker sent ERC20 Funding, tx hash {:02x}", funding_tx.tx_hash()); + log!("Taker sent ERC20 funding, tx hash {:02x}", funding_tx.tx_hash()); wait_for_confirmations(&taker_coin, &funding_tx, 60); @@ -1622,12 +1622,11 @@ fn send_and_refund_taker_funding_by_secret_erc20() { }; let funding_tx_refund = block_on(taker_coin.refund_taker_funding_secret(refund_args)).unwrap(); log!( - "Taker refunded ERC20 Funding by Secret, tx hash: {:02x}", + "Taker refunded ERC20 funding by secret, tx hash: {:02x}", funding_tx_refund.tx_hash() ); } -#[ignore] #[test] fn send_and_refund_taker_funding_timelock_eth() { let taker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init()); @@ -1637,9 +1636,9 @@ fn send_and_refund_taker_funding_timelock_eth() { let taker_secret_hash = sha256(&taker_secret).to_vec(); let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); - // TODO exceed funding_time_lock, as if TakerPaymentState.PaymentSent then - // timestamp should exceed payment pre-approve lock time - let funding_time_lock = now_sec() + 3000; + // exceed funding_time_lock, as if TakerPaymentState.PaymentSent then timestamp should exceed payment pre-approve lock time + let funding_time_lock = now_sec() - 3000; + // TODO need to impl taker approve to test exceeded payment_time_lock let payment_time_lock = now_sec() + 1000; let dex_fee = &DexFee::Standard("0.1".into()); @@ -1657,27 +1656,30 @@ fn send_and_refund_taker_funding_timelock_eth() { wait_for_confirmation_until: 0, }; let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); - log!("Taker sent ETH Funding, tx hash: {:02x}", funding_tx.tx_hash()); + log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); wait_for_confirmations(&taker_coin, &funding_tx, 60); - let refund_args = RefundFundingSecretArgs { - funding_tx: &funding_tx, - funding_time_lock, - payment_time_lock, - maker_pubkey: &taker_coin.derive_htlc_pubkey_v2(&[]), - taker_secret: &taker_secret, - taker_secret_hash: &taker_secret_hash, + let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash: &maker_secret_hash, - dex_fee, - premium_amount: Default::default(), - trading_amount: 1.into(), + taker_secret_hash: &taker_secret_hash, + }; + + let refund_args = RefundTakerPaymentArgs { + payment_tx: &funding_tx.to_bytes(), + funding_time_lock, + time_lock: payment_time_lock, + maker_pub: maker_pub.as_bytes(), + tx_type_with_secret_hash, swap_unique_data: &[], watcher_reward: false, + dex_fee, + premium_amount: BigDecimal::default(), + trading_amount: 1.into(), }; - let funding_tx_refund = block_on(taker_coin.refund_taker_funding_secret(refund_args)).unwrap(); + let funding_tx_refund = block_on(taker_coin.refund_taker_funding_timelock(refund_args)).unwrap(); log!( - "Taker refunded ETH Funding by Secret, tx hash: {:02x}", + "Taker refunded ETH funding after the pre-approval lock time was exceeded, tx hash: {:02x}", funding_tx_refund.tx_hash() ); } From c924520e42d9f191dcc05e39c75cb5d7e6be7be5 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 19 Jul 2024 18:08:07 +0700 Subject: [PATCH 102/233] eth tpu v2: test send_and_refund_taker_funding_timelock_erc20 --- .../tests/docker_tests/eth_docker_tests.rs | 60 ++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index f0dd0bd18d..cb9b039cc0 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1679,7 +1679,65 @@ fn send_and_refund_taker_funding_timelock_eth() { }; let funding_tx_refund = block_on(taker_coin.refund_taker_funding_timelock(refund_args)).unwrap(); log!( - "Taker refunded ETH funding after the pre-approval lock time was exceeded, tx hash: {:02x}", + "Taker refunded ETH funding after pre-approval lock time was exceeded, tx hash: {:02x}", + funding_tx_refund.tx_hash() + ); +} + +#[test] +fn send_and_refund_taker_funding_timelock_erc20() { + let erc20_conf = &erc20_dev_conf(&erc20_contract_checksum()); + let taker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init()); + let maker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init()); + + let taker_secret = vec![0; 32]; + let taker_secret_hash = sha256(&taker_secret).to_vec(); + let maker_secret = vec![1; 32]; + let maker_secret_hash = sha256(&maker_secret).to_vec(); + // exceed funding_time_lock, as if TakerPaymentState.PaymentSent then timestamp should exceed payment pre-approve lock time + let funding_time_lock = now_sec() - 3000; + // TODO need to impl taker approve to test exceeded payment_time_lock + let payment_time_lock = now_sec() + 1000; + + let dex_fee = &DexFee::Standard("0.1".into()); + let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); + let payment_args = SendTakerFundingArgs { + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + maker_pub: maker_pub.as_bytes(), + dex_fee, + premium_amount: BigDecimal::default(), + trading_amount: 1.into(), + swap_unique_data: &[], + wait_for_confirmation_until: now_sec() + 60, + }; + let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); + log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); + + wait_for_confirmations(&taker_coin, &funding_tx, 60); + + let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { + maker_secret_hash: &maker_secret_hash, + taker_secret_hash: &taker_secret_hash, + }; + + let refund_args = RefundTakerPaymentArgs { + payment_tx: &funding_tx.to_bytes(), + funding_time_lock, + time_lock: payment_time_lock, + maker_pub: maker_pub.as_bytes(), + tx_type_with_secret_hash, + swap_unique_data: &[], + watcher_reward: false, + dex_fee, + premium_amount: BigDecimal::default(), + trading_amount: 1.into(), + }; + let funding_tx_refund = block_on(taker_coin.refund_taker_funding_timelock(refund_args)).unwrap(); + log!( + "Taker refunded ERC20 funding after pre-approval lock time was exceeded, tx hash: {:02x}", funding_tx_refund.tx_hash() ); } From 69d2fbef0081ea9355b2b82d2a5165a945185e37 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 21 Jul 2024 12:18:38 +0700 Subject: [PATCH 103/233] doc comments --- mm2src/coins/eth.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index dc08b85f4d..b11402740a 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7120,6 +7120,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { self.refund_taker_funding_secret_impl(args).await } + /// checks taker payment status in etomic swap contract async fn search_for_taker_funding_spend( &self, _tx: &Self::Tx, @@ -7151,7 +7152,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { Ok(()) } - /// Eth doesnt use multisig + /// takerPaymentApprove is called here for EVM based chains async fn sign_and_send_taker_funding_spend( &self, _preimage: &TxPreimageWithSig, @@ -7191,6 +7192,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { Ok(()) } + /// spendTakerPayment is called here for EVM based chains async fn sign_and_broadcast_taker_payment_spend( &self, _preimage: &TxPreimageWithSig, From cac2d0db3b48d8c058471713859ffb3d47b61952 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 21 Jul 2024 12:37:28 +0700 Subject: [PATCH 104/233] review: remove gas_limit module from eth_swap_v2.rs --- mm2src/coins/eth/eth_swap_v2.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 4fa8b8154b..2280954c60 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,5 +1,4 @@ -use super::eth::{addr_from_raw_pubkey, gas_limit, wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, - TAKER_SWAP_V2}; +use super::eth::{addr_from_raw_pubkey, wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; use super::{SendTakerFundingArgs, Transaction, TransactionErr}; use enum_derives::EnumFromStringify; use ethabi::Token; @@ -55,7 +54,7 @@ impl EthCoin { payment_amount, Action::Call(taker_swap_v2_contract), data, - U256::from(gas_limit::ETH_PAYMENT), + U256::from(self.gas_limit.eth_payment), ) .compat() .await @@ -90,7 +89,7 @@ impl EthCoin { U256::from(0), Action::Call(taker_swap_v2_contract), data, - U256::from(gas_limit::ERC20_PAYMENT), + U256::from(self.gas_limit.erc20_payment), ) .compat() .await @@ -99,7 +98,7 @@ impl EthCoin { U256::from(0), Action::Call(taker_swap_v2_contract), data, - U256::from(gas_limit::ERC20_PAYMENT), + U256::from(self.gas_limit.erc20_payment), ) .compat() .await From 071a1f6ce428db2d995aa3b4d1bfc393bd2fd5eb Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 21 Jul 2024 16:25:26 +0700 Subject: [PATCH 105/233] review: use `etomic_swap_id` function --- mm2src/coins/eth.rs | 22 ---------------------- mm2src/coins/eth/eth_swap_v2.rs | 4 ++-- 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index b6e10c21c6..a4d6b39e12 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -838,28 +838,6 @@ impl EthCoinImpl { sha256(&input).to_vec() } - /// The id used to differentiate payments on Etomic swap smart contract. - /// For Taker Etomic Swap contract taker_secret_hash should be provided. - pub(crate) fn etomic_swap_v2_id( - &self, - funding_time_lock: u32, - payment_time_lock: u32, - secret_hash: &[u8], - ) -> Vec { - let funding_timelock_bytes = funding_time_lock.to_le_bytes(); - let payment_timelock_bytes = payment_time_lock.to_le_bytes(); - - let mut input = - Vec::with_capacity(funding_timelock_bytes.len() + payment_timelock_bytes.len() + secret_hash.len()); - input.extend( - funding_timelock_bytes - .iter() - .chain(payment_timelock_bytes.iter()) - .chain(secret_hash.iter()), - ); - sha256(&input).to_vec() - } - /// Try to parse address from string. pub fn address_from_str(&self, address: &str) -> Result { Ok(try_s!(valid_addr_from_str(address))) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 2280954c60..c85dd67c60 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -112,7 +112,7 @@ impl EthCoin { async fn prepare_taker_eth_funding_data(&self, args: &TakerFundingArgs<'_>) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("ethTakerPayment")?; - let id = self.etomic_swap_v2_id(args.funding_time_lock, args.payment_time_lock, args.taker_secret_hash); + let id = self.etomic_swap_id(args.payment_time_lock, args.maker_secret_hash); let data = function.encode_input(&[ Token::FixedBytes(id), Token::Uint(args.dex_fee), @@ -131,7 +131,7 @@ impl EthCoin { token_addr: Address, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("erc20TakerPayment")?; - let id = self.etomic_swap_v2_id(args.funding_time_lock, args.payment_time_lock, args.taker_secret_hash); + let id = self.etomic_swap_id(args.payment_time_lock, args.maker_secret_hash); let data = function.encode_input(&[ Token::FixedBytes(id), Token::Uint(args.payment_amount), From b3c66bd39b91e45f703e7a625268db66127448fd Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 21 Jul 2024 16:40:29 +0700 Subject: [PATCH 106/233] use etomic_swap_id in eth_swap_v2.rs, remove funding_time_lock from RefundTakerPaymentArgs --- mm2src/coins/eth/eth_swap_v2.rs | 11 +++-------- mm2src/coins/lp_coins.rs | 2 -- mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 1 - .../mm2_main/tests/docker_tests/eth_docker_tests.rs | 2 -- .../tests/docker_tests/swap_proto_v2_tests.rs | 1 - 5 files changed, 3 insertions(+), 14 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 396996e4f3..fc2b3f39ae 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,6 +1,7 @@ use super::eth::{wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; use super::{RefundFundingSecretArgs, RefundTakerPaymentArgs, SendTakerFundingArgs, SwapTxTypeWithSecretHash, Transaction, TransactionErr}; +use bitcrypto::sha256; use enum_derives::EnumFromStringify; use ethabi::Token; use ethcore_transaction::Action; @@ -25,7 +26,6 @@ struct TakerRefundSecretArgs<'a> { maker_address: Address, taker_secret: &'a [u8], maker_secret_hash: &'a [u8], - funding_time_lock: u32, payment_time_lock: u32, token_address: Address, } @@ -36,7 +36,6 @@ struct TakerRefundArgs<'a> { maker_address: Address, taker_secret_hash: &'a [u8], maker_secret_hash: &'a [u8], - funding_time_lock: u32, payment_time_lock: u32, token_address: Address, } @@ -155,7 +154,6 @@ impl EthCoin { )); // TODO add maker_pub created by legacy derive_htlc_pubkey support additionally? let maker_address = public_to_address(&Public::from_slice(args.maker_pub)); - let funding_time_lock: u32 = try_tx_s!(args.funding_time_lock.try_into()); let payment_time_lock: u32 = try_tx_s!(args.time_lock.try_into()); let (maker_secret_hash, taker_secret_hash) = match args.tx_type_with_secret_hash { SwapTxTypeWithSecretHash::TakerPaymentV2 { @@ -187,7 +185,6 @@ impl EthCoin { maker_address, taker_secret_hash, maker_secret_hash, - funding_time_lock, payment_time_lock, token_address, }; @@ -221,7 +218,6 @@ impl EthCoin { self.decimals )); let maker_address = public_to_address(args.maker_pubkey); - let funding_time_lock: u32 = try_tx_s!(args.funding_time_lock.try_into()); let payment_time_lock: u32 = try_tx_s!(args.payment_time_lock.try_into()); let (token_address, gas_limit) = match &self.coin_type { EthCoinType::Eth => (Address::default(), self.gas_limit.eth_sender_refund), @@ -241,7 +237,6 @@ impl EthCoin { maker_address, taker_secret: args.taker_secret, maker_secret_hash: args.maker_secret_hash, - funding_time_lock, payment_time_lock, token_address, }; @@ -326,7 +321,7 @@ impl EthCoin { args: TakerRefundArgs<'_>, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("refundTakerPaymentTimelock")?; - let id = self.etomic_swap_v2_id(args.funding_time_lock, args.payment_time_lock, args.taker_secret_hash); + let id = self.etomic_swap_id(args.payment_time_lock, args.maker_secret_hash); let data = function.encode_input(&[ Token::FixedBytes(id), Token::Uint(args.payment_amount), @@ -353,7 +348,7 @@ impl EthCoin { args: &TakerRefundSecretArgs<'_>, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("refundTakerPaymentSecret")?; - let id = self.etomic_swap_v2_id(args.funding_time_lock, args.payment_time_lock, args.taker_secret); + let id = self.etomic_swap_id(args.payment_time_lock, sha256(args.taker_secret).as_slice()); let data = function.encode_input(&[ Token::FixedBytes(id), Token::Uint(args.payment_amount), diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index cf9358f643..a33596fe4d 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -991,8 +991,6 @@ pub struct RefundPaymentArgs<'a> { #[derive(Debug)] pub struct RefundTakerPaymentArgs<'a> { pub payment_tx: &'a [u8], - /// Needed for taker refund as for eth taker swap id `etomic_swap_v2_id` was used - pub funding_time_lock: u64, pub time_lock: u64, pub maker_pub: &'a [u8], pub tx_type_with_secret_hash: SwapTxTypeWithSecretHash<'a>, diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs index 5a121efc82..6047ef7e98 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs @@ -1901,7 +1901,6 @@ impl Date: Mon, 22 Jul 2024 10:50:32 +0700 Subject: [PATCH 107/233] review: use fixed size arrays --- mm2src/coins/eth/eth_swap_v2.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index c85dd67c60..352a72d0f3 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -7,12 +7,12 @@ use ethereum_types::{Address, U256}; use futures::compat::Future01CompatExt; use std::convert::TryInto; -struct TakerFundingArgs<'a> { +struct TakerFundingArgs { dex_fee: U256, payment_amount: U256, maker_address: Address, - taker_secret_hash: &'a [u8], - maker_secret_hash: &'a [u8], + taker_secret_hash: [u8; 32], + maker_secret_hash: [u8; 32], funding_time_lock: u32, payment_time_lock: u32, } @@ -41,8 +41,8 @@ impl EthCoin { dex_fee, payment_amount, maker_address, - taker_secret_hash: args.taker_secret_hash, - maker_secret_hash: args.maker_secret_hash, + taker_secret_hash: try_tx_s!(args.taker_secret_hash.try_into()), + maker_secret_hash: try_tx_s!(args.maker_secret_hash.try_into()), funding_time_lock, payment_time_lock, }; @@ -110,9 +110,9 @@ impl EthCoin { } } - async fn prepare_taker_eth_funding_data(&self, args: &TakerFundingArgs<'_>) -> Result, PrepareTxDataError> { + async fn prepare_taker_eth_funding_data(&self, args: &TakerFundingArgs) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("ethTakerPayment")?; - let id = self.etomic_swap_id(args.payment_time_lock, args.maker_secret_hash); + let id = self.etomic_swap_id(args.payment_time_lock, &args.maker_secret_hash); let data = function.encode_input(&[ Token::FixedBytes(id), Token::Uint(args.dex_fee), @@ -127,11 +127,11 @@ impl EthCoin { async fn prepare_taker_erc20_funding_data( &self, - args: &TakerFundingArgs<'_>, + args: &TakerFundingArgs, token_addr: Address, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("erc20TakerPayment")?; - let id = self.etomic_swap_id(args.payment_time_lock, args.maker_secret_hash); + let id = self.etomic_swap_id(args.payment_time_lock, &args.maker_secret_hash); let data = function.encode_input(&[ Token::FixedBytes(id), Token::Uint(args.payment_amount), From ee9d9dced93e07a17dd6fc4da7b1d3b7b6ab32a9 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 22 Jul 2024 11:05:35 +0700 Subject: [PATCH 108/233] review: use fixed size arrays --- mm2src/coins/eth/eth_swap_v2.rs | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index c77c15b804..9c3df60f49 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -20,22 +20,22 @@ struct TakerFundingArgs { payment_time_lock: u32, } -struct TakerRefundSecretArgs<'a> { +struct TakerRefundSecretArgs { dex_fee: U256, payment_amount: U256, maker_address: Address, - taker_secret: &'a [u8], - maker_secret_hash: &'a [u8], + taker_secret: [u8; 32], + maker_secret_hash: [u8; 32], payment_time_lock: u32, token_address: Address, } -struct TakerRefundArgs<'a> { +struct TakerRefundArgs { dex_fee: U256, payment_amount: U256, maker_address: Address, - taker_secret_hash: &'a [u8], - maker_secret_hash: &'a [u8], + taker_secret_hash: [u8; 32], + maker_secret_hash: [u8; 32], payment_time_lock: u32, token_address: Address, } @@ -183,8 +183,8 @@ impl EthCoin { dex_fee, payment_amount, maker_address, - taker_secret_hash, - maker_secret_hash, + taker_secret_hash: try_tx_s!(taker_secret_hash.try_into()), + maker_secret_hash: try_tx_s!(maker_secret_hash.try_into()), payment_time_lock, token_address, }; @@ -209,6 +209,8 @@ impl EthCoin { .as_ref() .map(|contracts| contracts.taker_swap_v2_contract) .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; + let taker_secret = try_tx_s!(args.taker_secret.try_into()); + let maker_secret_hash = try_tx_s!(args.maker_secret_hash.try_into()); let dex_fee = try_tx_s!(wei_from_big_decimal( &args.dex_fee.fee_amount().to_decimal(), self.decimals @@ -235,8 +237,8 @@ impl EthCoin { dex_fee, payment_amount, maker_address, - taker_secret: args.taker_secret, - maker_secret_hash: args.maker_secret_hash, + taker_secret, + maker_secret_hash, payment_time_lock, token_address, }; @@ -318,10 +320,10 @@ impl EthCoin { /// address tokenAddress async fn prepare_taker_refund_payment_timelock_data( &self, - args: TakerRefundArgs<'_>, + args: TakerRefundArgs, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("refundTakerPaymentTimelock")?; - let id = self.etomic_swap_id(args.payment_time_lock, args.maker_secret_hash); + let id = self.etomic_swap_id(args.payment_time_lock, &args.maker_secret_hash); let data = function.encode_input(&[ Token::FixedBytes(id), Token::Uint(args.payment_amount), @@ -345,10 +347,10 @@ impl EthCoin { /// address tokenAddress async fn prepare_taker_refund_payment_secret_data( &self, - args: &TakerRefundSecretArgs<'_>, + args: &TakerRefundSecretArgs, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("refundTakerPaymentSecret")?; - let id = self.etomic_swap_id(args.payment_time_lock, sha256(args.taker_secret).as_slice()); + let id = self.etomic_swap_id(args.payment_time_lock, sha256(&args.taker_secret).as_slice()); let data = function.encode_input(&[ Token::FixedBytes(id), Token::Uint(args.payment_amount), From b971ad8be7b2c2e6939cf7aa2fb9310c8498d6e0 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 22 Jul 2024 17:26:21 +0700 Subject: [PATCH 109/233] update maker_swap_v2_bytes and taker_swap_v2_bytes --- mm2src/mm2_test_helpers/contract_bytes/maker_swap_v2_bytes | 2 +- mm2src/mm2_test_helpers/contract_bytes/taker_swap_v2_bytes | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mm2src/mm2_test_helpers/contract_bytes/maker_swap_v2_bytes b/mm2src/mm2_test_helpers/contract_bytes/maker_swap_v2_bytes index 5b8bda7350..5ac667f370 100644 --- a/mm2src/mm2_test_helpers/contract_bytes/maker_swap_v2_bytes +++ b/mm2src/mm2_test_helpers/contract_bytes/maker_swap_v2_bytes @@ -1 +1 @@ -6080604052348015600e575f80fd5b50611d9f8061001c5f395ff3fe608060405260043610610054575f3560e01c80631299a27a146100585780637466be601461008057806374a4788a1461009c5780639b949dee146100c4578063a53bc126146100ec578063efccb9eb14610114575b5f80fd5b348015610063575f80fd5b5061007e60048036038101906100799190611427565b610152565b005b61009a600480360381019061009591906114e9565b61044b565b005b3480156100a7575f80fd5b506100c260048036038101906100bd9190611427565b6106fc565b005b3480156100cf575f80fd5b506100ea60048036038101906100e59190611427565b6109f5565b005b3480156100f7575f80fd5b50610112600480360381019061010d9190611560565b610ced565b005b34801561011f575f80fd5b5061013a600480360381019061013591906115fd565b610fd2565b604051610149939291906116e4565b60405180910390f35b6001600381111561016657610165611671565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561019857610197611671565b5b146101d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101cf90611799565b60405180910390fd5b5f6003863387876002886040516020016101f291906117d7565b60405160208183030381529060405260405161020e9190611843565b602060405180830381855afa158015610229573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061024c919061186d565b87604051602001610262969594939291906118fd565b60405160208183030381529060405260405161027e9190611843565b602060405180830381855afa158015610299573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610323576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031a906119b6565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561035957610358611671565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161038d91906119e3565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610411573373ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f1935050505015801561040b573d5f803e3d5ffd5b50610442565b5f82905061044033888373ffffffffffffffffffffffffffffffffffffffff1661101e9092919063ffffffff16565b505b50505050505050565b5f600381111561045e5761045d611671565b5b5f808781526020019081526020015f205f0160189054906101000a900460ff1660038111156104905761048f611671565b5b146104d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c790611a6c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361053e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053590611ad4565b60405180910390fd5b5f3411610580576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057790611b62565b60405180910390fd5b5f600334863387875f60405160200161059e969594939291906118fd565b6040516020818303038152906040526040516105ba9190611843565b602060405180830381855afa1580156105d5573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018363ffffffff1681526020016001600381111561062157610620611671565b5b8152505f808881526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156106b5576106b4611671565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad866040516106ec91906119e3565b60405180910390a1505050505050565b600160038111156107105761070f611671565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561074257610741611671565b5b14610782576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161077990611799565b60405180910390fd5b5f600386863360028860405160200161079b91906117d7565b6040516020818303038152906040526040516107b79190611843565b602060405180830381855afa1580156107d2573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107f5919061186d565b878760405160200161080c969594939291906118fd565b6040516020818303038152906040526040516108289190611843565b602060405180830381855afa158015610843573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146108cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c4906119b6565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561090357610902611671565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd738760405161093791906119e3565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036109bb573373ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f193505050501580156109b5573d5f803e3d5ffd5b506109ec565b5f8290506109ea33888373ffffffffffffffffffffffffffffffffffffffff1661101e9092919063ffffffff16565b505b50505050505050565b60016003811115610a0957610a08611671565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff166003811115610a3b57610a3a611671565b5b14610a7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7290611799565b60405180910390fd5b5f6003868633878787604051602001610a99969594939291906118fd565b604051602081830303815290604052604051610ab59190611843565b602060405180830381855afa158015610ad0573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610b5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b51906119b6565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610bc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbc90611bf0565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610bfb57610bfa611671565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907287604051610c2f91906119e3565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610cb3573373ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f19350505050158015610cad573d5f803e3d5ffd5b50610ce4565b5f829050610ce233888373ffffffffffffffffffffffffffffffffffffffff1661101e9092919063ffffffff16565b505b50505050505050565b5f6003811115610d0057610cff611671565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115610d3257610d31611671565b5b14610d72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6990611a6c565b60405180910390fd5b5f8611610db4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dab90611c58565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610e22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1990611ad4565b60405180910390fd5b5f600387863387878b604051602001610e40969594939291906118fd565b604051602081830303815290604052604051610e5c9190611843565b602060405180830381855afa158015610e77573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018363ffffffff16815260200160016003811115610ec357610ec2611671565b5b8152505f808a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115610f5757610f56611671565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad88604051610f8e91906119e3565b60405180910390a15f869050610fc733308a8473ffffffffffffffffffffffffffffffffffffffff1661109d909392919063ffffffff16565b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b611098838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401611051929190611c94565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061111f565b505050565b611119848573ffffffffffffffffffffffffffffffffffffffff166323b872dd8686866040516024016110d293929190611cbb565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061111f565b50505050565b5f611149828473ffffffffffffffffffffffffffffffffffffffff166111b490919063ffffffff16565b90505f81511415801561116d57508080602001905181019061116b9190611d25565b155b156111af57826040517f5274afe70000000000000000000000000000000000000000000000000000000081526004016111a69190611d50565b60405180910390fd5b505050565b60606111c183835f6111c9565b905092915050565b60608147101561121057306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016112079190611d50565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516112389190611843565b5f6040518083038185875af1925050503d805f8114611272576040519150601f19603f3d011682016040523d82523d5f602084013e611277565b606091505b5091509150611287868383611292565b925050509392505050565b6060826112a7576112a28261131f565b611317565b5f82511480156112cd57505f8473ffffffffffffffffffffffffffffffffffffffff163b145b1561130f57836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016113069190611d50565b60405180910390fd5b819050611318565b5b9392505050565b5f815111156113315780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80fd5b5f819050919050565b61137981611367565b8114611383575f80fd5b50565b5f8135905061139481611370565b92915050565b5f819050919050565b6113ac8161139a565b81146113b6575f80fd5b50565b5f813590506113c7816113a3565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6113f6826113cd565b9050919050565b611406816113ec565b8114611410575f80fd5b50565b5f81359050611421816113fd565b92915050565b5f805f805f8060c0878903121561144157611440611363565b5b5f61144e89828a01611386565b965050602061145f89828a016113b9565b955050604061147089828a01611413565b945050606061148189828a01611386565b935050608061149289828a01611386565b92505060a06114a389828a01611413565b9150509295509295509295565b5f63ffffffff82169050919050565b6114c8816114b0565b81146114d2575f80fd5b50565b5f813590506114e3816114bf565b92915050565b5f805f805f60a0868803121561150257611501611363565b5b5f61150f88828901611386565b955050602061152088828901611413565b945050604061153188828901611386565b935050606061154288828901611386565b9250506080611553888289016114d5565b9150509295509295909350565b5f805f805f805f60e0888a03121561157b5761157a611363565b5b5f6115888a828b01611386565b97505060206115998a828b016113b9565b96505060406115aa8a828b01611413565b95505060606115bb8a828b01611413565b94505060806115cc8a828b01611386565b93505060a06115dd8a828b01611386565b92505060c06115ee8a828b016114d5565b91505092959891949750929550565b5f6020828403121561161257611611611363565b5b5f61161f84828501611386565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b61165c81611628565b82525050565b61166b816114b0565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600481106116af576116ae611671565b5b50565b5f8190506116bf8261169e565b919050565b5f6116ce826116b2565b9050919050565b6116de816116c4565b82525050565b5f6060820190506116f75f830186611653565b6117046020830185611662565b61171160408301846116d5565b949350505050565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f611783602a83611719565b915061178e82611729565b604082019050919050565b5f6020820190508181035f8301526117b081611777565b9050919050565b5f819050919050565b6117d16117cc82611367565b6117b7565b82525050565b5f6117e282846117c0565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f61181d826117f1565b61182781856117fb565b9350611837818560208601611805565b80840191505092915050565b5f61184e8284611813565b915081905092915050565b5f8151905061186781611370565b92915050565b5f6020828403121561188257611881611363565b5b5f61188f84828501611859565b91505092915050565b5f819050919050565b6118b26118ad8261139a565b611898565b82525050565b5f8160601b9050919050565b5f6118ce826118b8565b9050919050565b5f6118df826118c4565b9050919050565b6118f76118f2826113ec565b6118d5565b82525050565b5f61190882896118a1565b60208201915061191882886118e6565b60148201915061192882876118e6565b60148201915061193882866117c0565b60208201915061194882856117c0565b60208201915061195882846118e6565b601482019150819050979650505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f6119a0601383611719565b91506119ab8261196c565b602082019050919050565b5f6020820190508181035f8301526119cd81611994565b9050919050565b6119dd81611367565b82525050565b5f6020820190506119f65f8301846119d4565b92915050565b7f4d616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f611a56602483611719565b9150611a61826119fc565b604082019050919050565b5f6020820190508181035f830152611a8381611a4a565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f611abe601e83611719565b9150611ac982611a8a565b602082019050919050565b5f6020820190508181035f830152611aeb81611ab2565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f611b4c602383611719565b9150611b5782611af2565b604082019050919050565b5f6020820190508181035f830152611b7981611b40565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f611bda603883611719565b9150611be582611b80565b604082019050919050565b5f6020820190508181035f830152611c0781611bce565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f611c42601783611719565b9150611c4d82611c0e565b602082019050919050565b5f6020820190508181035f830152611c6f81611c36565b9050919050565b611c7f816113ec565b82525050565b611c8e8161139a565b82525050565b5f604082019050611ca75f830185611c76565b611cb46020830184611c85565b9392505050565b5f606082019050611cce5f830186611c76565b611cdb6020830185611c76565b611ce86040830184611c85565b949350505050565b5f8115159050919050565b611d0481611cf0565b8114611d0e575f80fd5b50565b5f81519050611d1f81611cfb565b92915050565b5f60208284031215611d3a57611d39611363565b5b5f611d4784828501611d11565b91505092915050565b5f602082019050611d635f830184611c76565b9291505056fea2646970667358221220565f86096f083c176a08cc3c220c01bd63eb7268584f034f3380299de3dac57f64736f6c63430008190033 \ No newline at end of file +6080604052348015600e575f80fd5b50611d9f8061001c5f395ff3fe608060405260043610610054575f3560e01c80631299a27a146100585780637466be601461008057806374a4788a1461009c5780639b949dee146100c4578063a53bc126146100ec578063efccb9eb14610114575b5f80fd5b348015610063575f80fd5b5061007e60048036038101906100799190611427565b610152565b005b61009a600480360381019061009591906114e9565b61044b565b005b3480156100a7575f80fd5b506100c260048036038101906100bd9190611427565b6106fc565b005b3480156100cf575f80fd5b506100ea60048036038101906100e59190611427565b6109f5565b005b3480156100f7575f80fd5b50610112600480360381019061010d9190611560565b610ced565b005b34801561011f575f80fd5b5061013a600480360381019061013591906115fd565b610fd2565b604051610149939291906116e4565b60405180910390f35b6001600381111561016657610165611671565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561019857610197611671565b5b146101d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101cf90611799565b60405180910390fd5b5f6003863387876002886040516020016101f291906117d7565b60405160208183030381529060405260405161020e9190611843565b602060405180830381855afa158015610229573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061024c919061186d565b87604051602001610262969594939291906118fd565b60405160208183030381529060405260405161027e9190611843565b602060405180830381855afa158015610299573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610323576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031a906119b6565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561035957610358611671565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161038d91906119e3565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610411573373ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f1935050505015801561040b573d5f803e3d5ffd5b50610442565b5f82905061044033888373ffffffffffffffffffffffffffffffffffffffff1661101e9092919063ffffffff16565b505b50505050505050565b5f600381111561045e5761045d611671565b5b5f808781526020019081526020015f205f0160189054906101000a900460ff1660038111156104905761048f611671565b5b146104d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c790611a6c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361053e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053590611ad4565b60405180910390fd5b5f3411610580576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057790611b62565b60405180910390fd5b5f600334863387875f60405160200161059e969594939291906118fd565b6040516020818303038152906040526040516105ba9190611843565b602060405180830381855afa1580156105d5573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018363ffffffff1681526020016001600381111561062157610620611671565b5b8152505f808881526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156106b5576106b4611671565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad866040516106ec91906119e3565b60405180910390a1505050505050565b600160038111156107105761070f611671565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561074257610741611671565b5b14610782576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161077990611799565b60405180910390fd5b5f600386863360028860405160200161079b91906117d7565b6040516020818303038152906040526040516107b79190611843565b602060405180830381855afa1580156107d2573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107f5919061186d565b878760405160200161080c969594939291906118fd565b6040516020818303038152906040526040516108289190611843565b602060405180830381855afa158015610843573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146108cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c4906119b6565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561090357610902611671565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd738760405161093791906119e3565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036109bb573373ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f193505050501580156109b5573d5f803e3d5ffd5b506109ec565b5f8290506109ea33888373ffffffffffffffffffffffffffffffffffffffff1661101e9092919063ffffffff16565b505b50505050505050565b60016003811115610a0957610a08611671565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff166003811115610a3b57610a3a611671565b5b14610a7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7290611799565b60405180910390fd5b5f6003868633878787604051602001610a99969594939291906118fd565b604051602081830303815290604052604051610ab59190611843565b602060405180830381855afa158015610ad0573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610b5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b51906119b6565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610bc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbc90611bf0565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610bfb57610bfa611671565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907287604051610c2f91906119e3565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610cb3573373ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f19350505050158015610cad573d5f803e3d5ffd5b50610ce4565b5f829050610ce233888373ffffffffffffffffffffffffffffffffffffffff1661101e9092919063ffffffff16565b505b50505050505050565b5f6003811115610d0057610cff611671565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115610d3257610d31611671565b5b14610d72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6990611a6c565b60405180910390fd5b5f8611610db4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dab90611c58565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610e22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1990611ad4565b60405180910390fd5b5f600387863387878b604051602001610e40969594939291906118fd565b604051602081830303815290604052604051610e5c9190611843565b602060405180830381855afa158015610e77573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018363ffffffff16815260200160016003811115610ec357610ec2611671565b5b8152505f808a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff02191690836003811115610f5757610f56611671565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad88604051610f8e91906119e3565b60405180910390a15f869050610fc733308a8473ffffffffffffffffffffffffffffffffffffffff1661109d909392919063ffffffff16565b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b611098838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401611051929190611c94565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061111f565b505050565b611119848573ffffffffffffffffffffffffffffffffffffffff166323b872dd8686866040516024016110d293929190611cbb565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061111f565b50505050565b5f611149828473ffffffffffffffffffffffffffffffffffffffff166111b490919063ffffffff16565b90505f81511415801561116d57508080602001905181019061116b9190611d25565b155b156111af57826040517f5274afe70000000000000000000000000000000000000000000000000000000081526004016111a69190611d50565b60405180910390fd5b505050565b60606111c183835f6111c9565b905092915050565b60608147101561121057306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016112079190611d50565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516112389190611843565b5f6040518083038185875af1925050503d805f8114611272576040519150601f19603f3d011682016040523d82523d5f602084013e611277565b606091505b5091509150611287868383611292565b925050509392505050565b6060826112a7576112a28261131f565b611317565b5f82511480156112cd57505f8473ffffffffffffffffffffffffffffffffffffffff163b145b1561130f57836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016113069190611d50565b60405180910390fd5b819050611318565b5b9392505050565b5f815111156113315780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80fd5b5f819050919050565b61137981611367565b8114611383575f80fd5b50565b5f8135905061139481611370565b92915050565b5f819050919050565b6113ac8161139a565b81146113b6575f80fd5b50565b5f813590506113c7816113a3565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6113f6826113cd565b9050919050565b611406816113ec565b8114611410575f80fd5b50565b5f81359050611421816113fd565b92915050565b5f805f805f8060c0878903121561144157611440611363565b5b5f61144e89828a01611386565b965050602061145f89828a016113b9565b955050604061147089828a01611413565b945050606061148189828a01611386565b935050608061149289828a01611386565b92505060a06114a389828a01611413565b9150509295509295509295565b5f63ffffffff82169050919050565b6114c8816114b0565b81146114d2575f80fd5b50565b5f813590506114e3816114bf565b92915050565b5f805f805f60a0868803121561150257611501611363565b5b5f61150f88828901611386565b955050602061152088828901611413565b945050604061153188828901611386565b935050606061154288828901611386565b9250506080611553888289016114d5565b9150509295509295909350565b5f805f805f805f60e0888a03121561157b5761157a611363565b5b5f6115888a828b01611386565b97505060206115998a828b016113b9565b96505060406115aa8a828b01611413565b95505060606115bb8a828b01611413565b94505060806115cc8a828b01611386565b93505060a06115dd8a828b01611386565b92505060c06115ee8a828b016114d5565b91505092959891949750929550565b5f6020828403121561161257611611611363565b5b5f61161f84828501611386565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b61165c81611628565b82525050565b61166b816114b0565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600481106116af576116ae611671565b5b50565b5f8190506116bf8261169e565b919050565b5f6116ce826116b2565b9050919050565b6116de816116c4565b82525050565b5f6060820190506116f75f830186611653565b6117046020830185611662565b61171160408301846116d5565b949350505050565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f611783602a83611719565b915061178e82611729565b604082019050919050565b5f6020820190508181035f8301526117b081611777565b9050919050565b5f819050919050565b6117d16117cc82611367565b6117b7565b82525050565b5f6117e282846117c0565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f61181d826117f1565b61182781856117fb565b9350611837818560208601611805565b80840191505092915050565b5f61184e8284611813565b915081905092915050565b5f8151905061186781611370565b92915050565b5f6020828403121561188257611881611363565b5b5f61188f84828501611859565b91505092915050565b5f819050919050565b6118b26118ad8261139a565b611898565b82525050565b5f8160601b9050919050565b5f6118ce826118b8565b9050919050565b5f6118df826118c4565b9050919050565b6118f76118f2826113ec565b6118d5565b82525050565b5f61190882896118a1565b60208201915061191882886118e6565b60148201915061192882876118e6565b60148201915061193882866117c0565b60208201915061194882856117c0565b60208201915061195882846118e6565b601482019150819050979650505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f6119a0601383611719565b91506119ab8261196c565b602082019050919050565b5f6020820190508181035f8301526119cd81611994565b9050919050565b6119dd81611367565b82525050565b5f6020820190506119f65f8301846119d4565b92915050565b7f4d616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f611a56602483611719565b9150611a61826119fc565b604082019050919050565b5f6020820190508181035f830152611a8381611a4a565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f611abe601e83611719565b9150611ac982611a8a565b602082019050919050565b5f6020820190508181035f830152611aeb81611ab2565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f611b4c602383611719565b9150611b5782611af2565b604082019050919050565b5f6020820190508181035f830152611b7981611b40565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f611bda603883611719565b9150611be582611b80565b604082019050919050565b5f6020820190508181035f830152611c0781611bce565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f611c42601783611719565b9150611c4d82611c0e565b602082019050919050565b5f6020820190508181035f830152611c6f81611c36565b9050919050565b611c7f816113ec565b82525050565b611c8e8161139a565b82525050565b5f604082019050611ca75f830185611c76565b611cb46020830184611c85565b9392505050565b5f606082019050611cce5f830186611c76565b611cdb6020830185611c76565b611ce86040830184611c85565b949350505050565b5f8115159050919050565b611d0481611cf0565b8114611d0e575f80fd5b50565b5f81519050611d1f81611cfb565b92915050565b5f60208284031215611d3a57611d39611363565b5b5f611d4784828501611d11565b91505092915050565b5f602082019050611d635f830184611c76565b9291505056fea26469706673582212200d7b67fe7b5e6829da1f56f14431b4ee61dc3a66fb17a79f0587fda0329d09ba64736f6c634300081a0033 \ No newline at end of file diff --git a/mm2src/mm2_test_helpers/contract_bytes/taker_swap_v2_bytes b/mm2src/mm2_test_helpers/contract_bytes/taker_swap_v2_bytes index 5394d75e8a..25960a6cc5 100644 --- a/mm2src/mm2_test_helpers/contract_bytes/taker_swap_v2_bytes +++ b/mm2src/mm2_test_helpers/contract_bytes/taker_swap_v2_bytes @@ -1 +1 @@ -60a060405234801561000f575f80fd5b50604051612a1b380380612a1b83398181016040528101906100319190610137565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361009f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610096906101e2565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505050610200565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610106826100dd565b9050919050565b610116816100fc565b8114610120575f80fd5b50565b5f815190506101318161010d565b92915050565b5f6020828403121561014c5761014b6100d9565b5b5f61015984828501610123565b91505092915050565b5f82825260208201905092915050565b7f66656541646472657373206d757374206e6f74206265207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f6101cc602383610162565b91506101d782610172565b604082019050919050565b5f6020820190508181035f8301526101f9816101c0565b9050919050565b6080516127f56102265f395f818161116d0152818161120801526115c401526127f55ff3fe60806040526004361061007a575f3560e01c80639b4603f21161004d5780639b4603f214610135578063cc90c19914610151578063d6a71eb414610179578063e06cf966146101a15761007a565b8063146e5b241461007e5780633e6af5f2146100a657806346b95ac7146100ce57806365e266171461010d575b5f80fd5b348015610089575f80fd5b506100a4600480360381019061009f91906119ef565b6101cb565b005b3480156100b1575f80fd5b506100cc60048036038101906100c791906119ef565b6103ae565b005b3480156100d9575f80fd5b506100f460048036038101906100ef9190611a8c565b6106bc565b6040516101049493929190611b82565b60405180910390f35b348015610118575f80fd5b50610133600480360381019061012e91906119ef565b61071d565b005b61014f600480360381019061014a9190611bef565b610b79565b005b34801561015c575f80fd5b50610177600480360381019061017291906119ef565b610ead565b005b348015610184575f80fd5b5061019f600480360381019061019a9190611c8c565b61125a565b005b3480156101ac575f80fd5b506101b56115c2565b6040516101c29190611d5f565b60405180910390f35b600160048111156101df576101de611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff16600481111561021157610210611b0f565b5b14610251576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024890611df8565b60405180910390fd5b5f6003878787338888886040516020016102719796959493929190611e9b565b60405160208183030381529060405260405161028d9190611f6d565b602060405180830381855afa1580156102a8573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610332576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032990611fcd565b60405180910390fd5b60025f808a81526020019081526020015f205f01601c6101000a81548160ff0219169083600481111561036857610367611b0f565b5b02179055507f9c45e43e2ef051f70491ffd5221bf02ab37e1324128714ef9610df5f24fc9fb58860405161039c9190611ffa565b60405180910390a15050505050505050565b600160048111156103c2576103c1611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660048111156103f4576103f3611b0f565b5b14610434576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042b90611df8565b60405180910390fd5b5f60038787873360028960405160200161044e9190612013565b60405160208183030381529060405260405161046a9190611f6d565b602060405180830381855afa158015610485573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906104a89190612041565b88886040516020016104c09796959493929190611e9b565b6040516020818303038152906040526040516104dc9190611f6d565b602060405180830381855afa1580156104f7573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610581576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057890611fcd565b60405180910390fd5b60045f808a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156105b7576105b6611b0f565b5b02179055507f45169a52eef651b20a81474b50b8a5d83225225fcd097ef3cf7952d9ab304f2788856040516105ed92919061206c565b60405180910390a15f868861060291906120c0565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610680573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f1935050505015801561067a573d5f803e3d5ffd5b506106b1565b5f8390506106af33838373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900463ffffffff1690805f01601c9054906101000a900460ff16905084565b6001600481111561073157610730611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff16600481111561076357610762611b0f565b5b14806107b257506002600481111561077e5761077d611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660048111156107b0576107af611b0f565b5b145b6107f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e890612163565b60405180910390fd5b5f6003878787338888886040516020016108119796959493929190611e9b565b60405160208183030381529060405260405161082d9190611f6d565b602060405180830381855afa158015610848573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146108d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c990611fcd565b60405180910390fd5b600260048111156108e6576108e5611b0f565b5b5f808a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561091857610917611b0f565b5b03610989575f808981526020019081526020015f205f0160189054906101000a900463ffffffff1663ffffffff16421015610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097f906121f1565b60405180910390fd5b5b6001600481111561099d5761099c611b0f565b5b5f808a81526020019081526020015f205f01601c9054906101000a900460ff1660048111156109cf576109ce611b0f565b5b03610a40575f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610a3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a369061227f565b60405180910390fd5b5b60045f808a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610a7657610a75611b0f565b5b02179055507fbdd7a4be6d82798a500b59077706b12d3f45acf5504828919f92501307b2b95388604051610aaa9190611ffa565b60405180910390a15f8688610abf91906120c0565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b3d573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015610b37573d5f803e3d5ffd5b50610b6e565b5f839050610b6c33838373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b505050505050505050565b5f6004811115610b8c57610b8b611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff166004811115610bbe57610bbd611b0f565b5b14610bfe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf59061230d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610c6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c639061239b565b60405180910390fd5b5f3411610cae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca590612429565b60405180910390fd5b853411610cf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce7906124b7565b60405180910390fd5b5f60038734610cff91906124d5565b88883389895f604051602001610d1b9796959493929190611e9b565b604051602081830303815290604052604051610d379190611f6d565b602060405180830381855afa158015610d52573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115610daa57610da9611b0f565b5b8152505f808a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115610e6457610e63611b0f565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd93588604051610e9b9190611ffa565b60405180910390a15050505050505050565b60026004811115610ec157610ec0611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff166004811115610ef357610ef2611b0f565b5b14610f33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2a90612578565b60405180910390fd5b5f60038787338888600289604051602001610f4e9190612013565b604051602081830303815290604052604051610f6a9190611f6d565b602060405180830381855afa158015610f85573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610fa89190612041565b88604051602001610fbf9796959493929190611e9b565b604051602081830303815290604052604051610fdb9190611f6d565b602060405180830381855afa158015610ff6573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611080576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107790611fcd565b60405180910390fd5b60035f808a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156110b6576110b5611b0f565b5b02179055507f0d0da0df275f85bed3a5fe7ae79f3559341a3f9ccd8e010133438135bda00a8788846040516110ec92919061206c565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111d4573373ffffffffffffffffffffffffffffffffffffffff166108fc8890811502906040515f60405180830381858888f1935050505015801561116a573d5f803e3d5ffd5b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f193505050501580156111ce573d5f803e3d5ffd5b50611250565b5f82905061120333898373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b61124e7f0000000000000000000000000000000000000000000000000000000000000000888373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b5050505050505050565b5f600481111561126d5761126c611b0f565b5b5f808b81526020019081526020015f205f01601c9054906101000a900460ff16600481111561129f5761129e611b0f565b5b146112df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d690612606565b60405180910390fd5b5f8811611321576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113189061266e565b60405180910390fd5b5f8711611363576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135a906126d6565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c89061239b565b60405180910390fd5b5f60038989883389898d6040516020016113f19796959493929190611e9b565b60405160208183030381529060405260405161140d9190611f6d565b602060405180830381855afa158015611428573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff168152602001600160048111156114805761147f611b0f565b5b8152505f808c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff0219169083600481111561153a57611539611b0f565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358a6040516115719190611ffa565b60405180910390a15f8790506115b533308b8d61158e91906120c0565b8473ffffffffffffffffffffffffffffffffffffffff16611665909392919063ffffffff16565b5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b611660838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401611619929190612703565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506116e7565b505050565b6116e1848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161169a9392919061272a565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506116e7565b50505050565b5f611711828473ffffffffffffffffffffffffffffffffffffffff1661177c90919063ffffffff16565b90505f8151141580156117355750808060200190518101906117339190612794565b155b1561177757826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161176e9190611d5f565b60405180910390fd5b505050565b606061178983835f611791565b905092915050565b6060814710156117d857306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016117cf9190611d5f565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516118009190611f6d565b5f6040518083038185875af1925050503d805f811461183a576040519150601f19603f3d011682016040523d82523d5f602084013e61183f565b606091505b509150915061184f86838361185a565b925050509392505050565b60608261186f5761186a826118e7565b6118df565b5f825114801561189557505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156118d757836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016118ce9190611d5f565b60405180910390fd5b8190506118e0565b5b9392505050565b5f815111156118f95780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80fd5b5f819050919050565b6119418161192f565b811461194b575f80fd5b50565b5f8135905061195c81611938565b92915050565b5f819050919050565b61197481611962565b811461197e575f80fd5b50565b5f8135905061198f8161196b565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6119be82611995565b9050919050565b6119ce816119b4565b81146119d8575f80fd5b50565b5f813590506119e9816119c5565b92915050565b5f805f805f805f60e0888a031215611a0a57611a0961192b565b5b5f611a178a828b0161194e565b9750506020611a288a828b01611981565b9650506040611a398a828b01611981565b9550506060611a4a8a828b016119db565b9450506080611a5b8a828b0161194e565b93505060a0611a6c8a828b0161194e565b92505060c0611a7d8a828b016119db565b91505092959891949750929550565b5f60208284031215611aa157611aa061192b565b5b5f611aae8482850161194e565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b611aeb81611ab7565b82525050565b5f63ffffffff82169050919050565b611b0981611af1565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60058110611b4d57611b4c611b0f565b5b50565b5f819050611b5d82611b3c565b919050565b5f611b6c82611b50565b9050919050565b611b7c81611b62565b82525050565b5f608082019050611b955f830187611ae2565b611ba26020830186611b00565b611baf6040830185611b00565b611bbc6060830184611b73565b95945050505050565b611bce81611af1565b8114611bd8575f80fd5b50565b5f81359050611be981611bc5565b92915050565b5f805f805f805f60e0888a031215611c0a57611c0961192b565b5b5f611c178a828b0161194e565b9750506020611c288a828b01611981565b9650506040611c398a828b016119db565b9550506060611c4a8a828b0161194e565b9450506080611c5b8a828b0161194e565b93505060a0611c6c8a828b01611bdb565b92505060c0611c7d8a828b01611bdb565b91505092959891949750929550565b5f805f805f805f805f6101208a8c031215611caa57611ca961192b565b5b5f611cb78c828d0161194e565b9950506020611cc88c828d01611981565b9850506040611cd98c828d01611981565b9750506060611cea8c828d016119db565b9650506080611cfb8c828d016119db565b95505060a0611d0c8c828d0161194e565b94505060c0611d1d8c828d0161194e565b93505060e0611d2e8c828d01611bdb565b925050610100611d408c828d01611bdb565b9150509295985092959850929598565b611d59816119b4565b82525050565b5f602082019050611d725f830184611d50565b92915050565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f611de2602a83611d78565b9150611ded82611d88565b604082019050919050565b5f6020820190508181035f830152611e0f81611dd6565b9050919050565b5f819050919050565b611e30611e2b82611962565b611e16565b82525050565b5f8160601b9050919050565b5f611e4c82611e36565b9050919050565b5f611e5d82611e42565b9050919050565b611e75611e70826119b4565b611e53565b82525050565b5f819050919050565b611e95611e908261192f565b611e7b565b82525050565b5f611ea6828a611e1f565b602082019150611eb68289611e1f565b602082019150611ec68288611e64565b601482019150611ed68287611e64565b601482019150611ee68286611e84565b602082019150611ef68285611e84565b602082019150611f068284611e64565b60148201915081905098975050505050505050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f611f4782611f1b565b611f518185611f25565b9350611f61818560208601611f2f565b80840191505092915050565b5f611f788284611f3d565b915081905092915050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f611fb7601383611d78565b9150611fc282611f83565b602082019050919050565b5f6020820190508181035f830152611fe481611fab565b9050919050565b611ff48161192f565b82525050565b5f60208201905061200d5f830184611feb565b92915050565b5f61201e8284611e84565b60208201915081905092915050565b5f8151905061203b81611938565b92915050565b5f602082840312156120565761205561192b565b5b5f6120638482850161202d565b91505092915050565b5f60408201905061207f5f830185611feb565b61208c6020830184611feb565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6120ca82611962565b91506120d583611962565b92508282019050808211156120ed576120ec612093565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e74206f722054616b6572417070726f7665640000000000602082015250565b5f61214d603b83611d78565b9150612158826120f3565b604082019050919050565b5f6020820190508181035f83015261217a81612141565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f6121db603883611d78565b91506121e682612181565b604082019050919050565b5f6020820190508181035f830152612208816121cf565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e74207072652d617070726f7665206c6f636b2074696d65000000602082015250565b5f612269603d83611d78565b91506122748261220f565b604082019050919050565b5f6020820190508181035f8301526122968161225d565b9050919050565b7f54616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f6122f7602483611d78565b91506123028261229d565b604082019050919050565b5f6020820190508181035f830152612324816122eb565b9050919050565b7f5265636569766572206d757374206e6f74206265207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f612385602183611d78565b91506123908261232b565b604082019050919050565b5f6020820190508181035f8301526123b281612379565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f612413602383611d78565b915061241e826123b9565b604082019050919050565b5f6020820190508181035f83015261244081612407565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e20645f8201527f6578206665650000000000000000000000000000000000000000000000000000602082015250565b5f6124a1602683611d78565b91506124ac82612447565b604082019050919050565b5f6020820190508181035f8301526124ce81612495565b9050919050565b5f6124df82611962565b91506124ea83611962565b925082820390508181111561250257612501612093565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520545f8201527f616b6572417070726f7665640000000000000000000000000000000000000000602082015250565b5f612562602c83611d78565b915061256d82612508565b604082019050919050565b5f6020820190508181035f83015261258f81612556565b9050919050565b7f4552433230207632207061796d656e7420697320616c726561647920696e69745f8201527f69616c697a656400000000000000000000000000000000000000000000000000602082015250565b5f6125f0602783611d78565b91506125fb82612596565b604082019050919050565b5f6020820190508181035f83015261261d816125e4565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f612658601783611d78565b915061266382612624565b602082019050919050565b5f6020820190508181035f8301526126858161264c565b9050919050565b7f44657820666565206d757374206e6f74206265207a65726f00000000000000005f82015250565b5f6126c0601883611d78565b91506126cb8261268c565b602082019050919050565b5f6020820190508181035f8301526126ed816126b4565b9050919050565b6126fd81611962565b82525050565b5f6040820190506127165f830185611d50565b61272360208301846126f4565b9392505050565b5f60608201905061273d5f830186611d50565b61274a6020830185611d50565b61275760408301846126f4565b949350505050565b5f8115159050919050565b6127738161275f565b811461277d575f80fd5b50565b5f8151905061278e8161276a565b92915050565b5f602082840312156127a9576127a861192b565b5b5f6127b684828501612780565b9150509291505056fea2646970667358221220fd2a736cddd6ebbd2831b0e65fb5470ffebd789dc32c1d3782ce69362e16fae564736f6c63430008190033 \ No newline at end of file +60a060405234801561000f575f80fd5b50604051612a1b380380612a1b83398181016040528101906100319190610137565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361009f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610096906101e2565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505050610200565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610106826100dd565b9050919050565b610116816100fc565b8114610120575f80fd5b50565b5f815190506101318161010d565b92915050565b5f6020828403121561014c5761014b6100d9565b5b5f61015984828501610123565b91505092915050565b5f82825260208201905092915050565b7f66656541646472657373206d757374206e6f74206265207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f6101cc602383610162565b91506101d782610172565b604082019050919050565b5f6020820190508181035f8301526101f9816101c0565b9050919050565b6080516127f56102265f395f818161116d0152818161120801526115c401526127f55ff3fe60806040526004361061007a575f3560e01c80639b4603f21161004d5780639b4603f214610135578063cc90c19914610151578063d6a71eb414610179578063e06cf966146101a15761007a565b8063146e5b241461007e5780633e6af5f2146100a657806346b95ac7146100ce57806365e266171461010d575b5f80fd5b348015610089575f80fd5b506100a4600480360381019061009f91906119ef565b6101cb565b005b3480156100b1575f80fd5b506100cc60048036038101906100c791906119ef565b6103ae565b005b3480156100d9575f80fd5b506100f460048036038101906100ef9190611a8c565b6106bc565b6040516101049493929190611b82565b60405180910390f35b348015610118575f80fd5b50610133600480360381019061012e91906119ef565b61071d565b005b61014f600480360381019061014a9190611bef565b610b79565b005b34801561015c575f80fd5b50610177600480360381019061017291906119ef565b610ead565b005b348015610184575f80fd5b5061019f600480360381019061019a9190611c8c565b61125a565b005b3480156101ac575f80fd5b506101b56115c2565b6040516101c29190611d5f565b60405180910390f35b600160048111156101df576101de611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff16600481111561021157610210611b0f565b5b14610251576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024890611df8565b60405180910390fd5b5f6003878787338888886040516020016102719796959493929190611e9b565b60405160208183030381529060405260405161028d9190611f6d565b602060405180830381855afa1580156102a8573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610332576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032990611fcd565b60405180910390fd5b60025f808a81526020019081526020015f205f01601c6101000a81548160ff0219169083600481111561036857610367611b0f565b5b02179055507f9c45e43e2ef051f70491ffd5221bf02ab37e1324128714ef9610df5f24fc9fb58860405161039c9190611ffa565b60405180910390a15050505050505050565b600160048111156103c2576103c1611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660048111156103f4576103f3611b0f565b5b14610434576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042b90611df8565b60405180910390fd5b5f60038787873360028960405160200161044e9190612013565b60405160208183030381529060405260405161046a9190611f6d565b602060405180830381855afa158015610485573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906104a89190612041565b88886040516020016104c09796959493929190611e9b565b6040516020818303038152906040526040516104dc9190611f6d565b602060405180830381855afa1580156104f7573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610581576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057890611fcd565b60405180910390fd5b60045f808a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156105b7576105b6611b0f565b5b02179055507f45169a52eef651b20a81474b50b8a5d83225225fcd097ef3cf7952d9ab304f2788856040516105ed92919061206c565b60405180910390a15f868861060291906120c0565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610680573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f1935050505015801561067a573d5f803e3d5ffd5b506106b1565b5f8390506106af33838373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900463ffffffff1690805f01601c9054906101000a900460ff16905084565b6001600481111561073157610730611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff16600481111561076357610762611b0f565b5b14806107b257506002600481111561077e5761077d611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660048111156107b0576107af611b0f565b5b145b6107f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e890612163565b60405180910390fd5b5f6003878787338888886040516020016108119796959493929190611e9b565b60405160208183030381529060405260405161082d9190611f6d565b602060405180830381855afa158015610848573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146108d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c990611fcd565b60405180910390fd5b600260048111156108e6576108e5611b0f565b5b5f808a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561091857610917611b0f565b5b03610989575f808981526020019081526020015f205f0160189054906101000a900463ffffffff1663ffffffff16421015610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097f906121f1565b60405180910390fd5b5b6001600481111561099d5761099c611b0f565b5b5f808a81526020019081526020015f205f01601c9054906101000a900460ff1660048111156109cf576109ce611b0f565b5b03610a40575f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610a3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a369061227f565b60405180910390fd5b5b60045f808a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610a7657610a75611b0f565b5b02179055507fbdd7a4be6d82798a500b59077706b12d3f45acf5504828919f92501307b2b95388604051610aaa9190611ffa565b60405180910390a15f8688610abf91906120c0565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b3d573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015610b37573d5f803e3d5ffd5b50610b6e565b5f839050610b6c33838373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b505050505050505050565b5f6004811115610b8c57610b8b611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff166004811115610bbe57610bbd611b0f565b5b14610bfe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf59061230d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610c6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c639061239b565b60405180910390fd5b5f3411610cae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca590612429565b60405180910390fd5b853411610cf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce7906124b7565b60405180910390fd5b5f60038734610cff91906124d5565b88883389895f604051602001610d1b9796959493929190611e9b565b604051602081830303815290604052604051610d379190611f6d565b602060405180830381855afa158015610d52573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115610daa57610da9611b0f565b5b8152505f808a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115610e6457610e63611b0f565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd93588604051610e9b9190611ffa565b60405180910390a15050505050505050565b60026004811115610ec157610ec0611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff166004811115610ef357610ef2611b0f565b5b14610f33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2a90612578565b60405180910390fd5b5f60038787338888600289604051602001610f4e9190612013565b604051602081830303815290604052604051610f6a9190611f6d565b602060405180830381855afa158015610f85573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610fa89190612041565b88604051602001610fbf9796959493929190611e9b565b604051602081830303815290604052604051610fdb9190611f6d565b602060405180830381855afa158015610ff6573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611080576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107790611fcd565b60405180910390fd5b60035f808a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156110b6576110b5611b0f565b5b02179055507f0d0da0df275f85bed3a5fe7ae79f3559341a3f9ccd8e010133438135bda00a8788846040516110ec92919061206c565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111d4573373ffffffffffffffffffffffffffffffffffffffff166108fc8890811502906040515f60405180830381858888f1935050505015801561116a573d5f803e3d5ffd5b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f193505050501580156111ce573d5f803e3d5ffd5b50611250565b5f82905061120333898373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b61124e7f0000000000000000000000000000000000000000000000000000000000000000888373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b5050505050505050565b5f600481111561126d5761126c611b0f565b5b5f808b81526020019081526020015f205f01601c9054906101000a900460ff16600481111561129f5761129e611b0f565b5b146112df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d690612606565b60405180910390fd5b5f8811611321576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113189061266e565b60405180910390fd5b5f8711611363576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135a906126d6565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c89061239b565b60405180910390fd5b5f60038989883389898d6040516020016113f19796959493929190611e9b565b60405160208183030381529060405260405161140d9190611f6d565b602060405180830381855afa158015611428573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff168152602001600160048111156114805761147f611b0f565b5b8152505f808c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff0219169083600481111561153a57611539611b0f565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358a6040516115719190611ffa565b60405180910390a15f8790506115b533308b8d61158e91906120c0565b8473ffffffffffffffffffffffffffffffffffffffff16611665909392919063ffffffff16565b5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b611660838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401611619929190612703565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506116e7565b505050565b6116e1848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161169a9392919061272a565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506116e7565b50505050565b5f611711828473ffffffffffffffffffffffffffffffffffffffff1661177c90919063ffffffff16565b90505f8151141580156117355750808060200190518101906117339190612794565b155b1561177757826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161176e9190611d5f565b60405180910390fd5b505050565b606061178983835f611791565b905092915050565b6060814710156117d857306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016117cf9190611d5f565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516118009190611f6d565b5f6040518083038185875af1925050503d805f811461183a576040519150601f19603f3d011682016040523d82523d5f602084013e61183f565b606091505b509150915061184f86838361185a565b925050509392505050565b60608261186f5761186a826118e7565b6118df565b5f825114801561189557505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156118d757836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016118ce9190611d5f565b60405180910390fd5b8190506118e0565b5b9392505050565b5f815111156118f95780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80fd5b5f819050919050565b6119418161192f565b811461194b575f80fd5b50565b5f8135905061195c81611938565b92915050565b5f819050919050565b61197481611962565b811461197e575f80fd5b50565b5f8135905061198f8161196b565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6119be82611995565b9050919050565b6119ce816119b4565b81146119d8575f80fd5b50565b5f813590506119e9816119c5565b92915050565b5f805f805f805f60e0888a031215611a0a57611a0961192b565b5b5f611a178a828b0161194e565b9750506020611a288a828b01611981565b9650506040611a398a828b01611981565b9550506060611a4a8a828b016119db565b9450506080611a5b8a828b0161194e565b93505060a0611a6c8a828b0161194e565b92505060c0611a7d8a828b016119db565b91505092959891949750929550565b5f60208284031215611aa157611aa061192b565b5b5f611aae8482850161194e565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b611aeb81611ab7565b82525050565b5f63ffffffff82169050919050565b611b0981611af1565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60058110611b4d57611b4c611b0f565b5b50565b5f819050611b5d82611b3c565b919050565b5f611b6c82611b50565b9050919050565b611b7c81611b62565b82525050565b5f608082019050611b955f830187611ae2565b611ba26020830186611b00565b611baf6040830185611b00565b611bbc6060830184611b73565b95945050505050565b611bce81611af1565b8114611bd8575f80fd5b50565b5f81359050611be981611bc5565b92915050565b5f805f805f805f60e0888a031215611c0a57611c0961192b565b5b5f611c178a828b0161194e565b9750506020611c288a828b01611981565b9650506040611c398a828b016119db565b9550506060611c4a8a828b0161194e565b9450506080611c5b8a828b0161194e565b93505060a0611c6c8a828b01611bdb565b92505060c0611c7d8a828b01611bdb565b91505092959891949750929550565b5f805f805f805f805f6101208a8c031215611caa57611ca961192b565b5b5f611cb78c828d0161194e565b9950506020611cc88c828d01611981565b9850506040611cd98c828d01611981565b9750506060611cea8c828d016119db565b9650506080611cfb8c828d016119db565b95505060a0611d0c8c828d0161194e565b94505060c0611d1d8c828d0161194e565b93505060e0611d2e8c828d01611bdb565b925050610100611d408c828d01611bdb565b9150509295985092959850929598565b611d59816119b4565b82525050565b5f602082019050611d725f830184611d50565b92915050565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f611de2602a83611d78565b9150611ded82611d88565b604082019050919050565b5f6020820190508181035f830152611e0f81611dd6565b9050919050565b5f819050919050565b611e30611e2b82611962565b611e16565b82525050565b5f8160601b9050919050565b5f611e4c82611e36565b9050919050565b5f611e5d82611e42565b9050919050565b611e75611e70826119b4565b611e53565b82525050565b5f819050919050565b611e95611e908261192f565b611e7b565b82525050565b5f611ea6828a611e1f565b602082019150611eb68289611e1f565b602082019150611ec68288611e64565b601482019150611ed68287611e64565b601482019150611ee68286611e84565b602082019150611ef68285611e84565b602082019150611f068284611e64565b60148201915081905098975050505050505050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f611f4782611f1b565b611f518185611f25565b9350611f61818560208601611f2f565b80840191505092915050565b5f611f788284611f3d565b915081905092915050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f611fb7601383611d78565b9150611fc282611f83565b602082019050919050565b5f6020820190508181035f830152611fe481611fab565b9050919050565b611ff48161192f565b82525050565b5f60208201905061200d5f830184611feb565b92915050565b5f61201e8284611e84565b60208201915081905092915050565b5f8151905061203b81611938565b92915050565b5f602082840312156120565761205561192b565b5b5f6120638482850161202d565b91505092915050565b5f60408201905061207f5f830185611feb565b61208c6020830184611feb565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6120ca82611962565b91506120d583611962565b92508282019050808211156120ed576120ec612093565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e74206f722054616b6572417070726f7665640000000000602082015250565b5f61214d603b83611d78565b9150612158826120f3565b604082019050919050565b5f6020820190508181035f83015261217a81612141565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f6121db603883611d78565b91506121e682612181565b604082019050919050565b5f6020820190508181035f830152612208816121cf565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e74207072652d617070726f7665206c6f636b2074696d65000000602082015250565b5f612269603d83611d78565b91506122748261220f565b604082019050919050565b5f6020820190508181035f8301526122968161225d565b9050919050565b7f54616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f6122f7602483611d78565b91506123028261229d565b604082019050919050565b5f6020820190508181035f830152612324816122eb565b9050919050565b7f5265636569766572206d757374206e6f74206265207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f612385602183611d78565b91506123908261232b565b604082019050919050565b5f6020820190508181035f8301526123b281612379565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f612413602383611d78565b915061241e826123b9565b604082019050919050565b5f6020820190508181035f83015261244081612407565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e20645f8201527f6578206665650000000000000000000000000000000000000000000000000000602082015250565b5f6124a1602683611d78565b91506124ac82612447565b604082019050919050565b5f6020820190508181035f8301526124ce81612495565b9050919050565b5f6124df82611962565b91506124ea83611962565b925082820390508181111561250257612501612093565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520545f8201527f616b6572417070726f7665640000000000000000000000000000000000000000602082015250565b5f612562602c83611d78565b915061256d82612508565b604082019050919050565b5f6020820190508181035f83015261258f81612556565b9050919050565b7f4552433230207632207061796d656e7420697320616c726561647920696e69745f8201527f69616c697a656400000000000000000000000000000000000000000000000000602082015250565b5f6125f0602783611d78565b91506125fb82612596565b604082019050919050565b5f6020820190508181035f83015261261d816125e4565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f612658601783611d78565b915061266382612624565b602082019050919050565b5f6020820190508181035f8301526126858161264c565b9050919050565b7f44657820666565206d757374206e6f74206265207a65726f00000000000000005f82015250565b5f6126c0601883611d78565b91506126cb8261268c565b602082019050919050565b5f6020820190508181035f8301526126ed816126b4565b9050919050565b6126fd81611962565b82525050565b5f6040820190506127165f830185611d50565b61272360208301846126f4565b9392505050565b5f60608201905061273d5f830186611d50565b61274a6020830185611d50565b61275760408301846126f4565b949350505050565b5f8115159050919050565b6127738161275f565b811461277d575f80fd5b50565b5f8151905061278e8161276a565b92915050565b5f602082840312156127a9576127a861192b565b5b5f6127b684828501612780565b9150509291505056fea2646970667358221220fdfd279e725ae77372fd2984ed85918b447664a0bbfc3fa6036a0cb26bbaf52264736f6c634300081a0033 \ No newline at end of file From c26c7a51154c46dcdbc808378b59e356d72459cc Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 22 Jul 2024 17:29:30 +0700 Subject: [PATCH 110/233] ignore tendermint tests --- .../tests/docker_tests/docker_tests_common.rs | 4 ++++ .../tests/docker_tests/tendermint_tests.rs | 17 +++++++++++++++++ mm2src/mm2_main/tests/docker_tests_main.rs | 19 ++++++++++--------- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 0b92c4d58d..cc1790cb0a 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -377,6 +377,7 @@ pub fn geth_docker_node<'a>(docker: &'a Cli, ticker: &'static str, port: u16) -> } } +#[allow(dead_code)] pub fn nucleus_node(docker: &'_ Cli, runtime_dir: PathBuf) -> DockerNode<'_> { let nucleus_node_runtime_dir = runtime_dir.join("nucleus-testnet-data"); assert!(nucleus_node_runtime_dir.exists()); @@ -393,6 +394,7 @@ pub fn nucleus_node(docker: &'_ Cli, runtime_dir: PathBuf) -> DockerNode<'_> { } } +#[allow(dead_code)] pub fn atom_node(docker: &'_ Cli, runtime_dir: PathBuf) -> DockerNode<'_> { let atom_node_runtime_dir = runtime_dir.join("atom-testnet-data"); assert!(atom_node_runtime_dir.exists()); @@ -409,6 +411,7 @@ pub fn atom_node(docker: &'_ Cli, runtime_dir: PathBuf) -> DockerNode<'_> { } } +#[allow(dead_code)] pub fn ibc_relayer_node(docker: &'_ Cli, runtime_dir: PathBuf) -> DockerNode<'_> { let relayer_node_runtime_dir = runtime_dir.join("ibc-relayer-data"); assert!(relayer_node_runtime_dir.exists()); @@ -1145,6 +1148,7 @@ async fn get_current_gas_limit(web3: &Web3) { } } +#[allow(dead_code)] pub fn wait_until_relayer_container_is_ready(container_id: &str) { const Q_RESULT: &str = "0: nucleus-atom -> chns(✔) clnts(✔) conn(✔) (nucleus-testnet<>cosmoshub-testnet)"; diff --git a/mm2src/mm2_main/tests/docker_tests/tendermint_tests.rs b/mm2src/mm2_main/tests/docker_tests/tendermint_tests.rs index 80e4470d70..0e7e09e181 100644 --- a/mm2src/mm2_main/tests/docker_tests/tendermint_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/tendermint_tests.rs @@ -21,6 +21,7 @@ const NUCLEUS_TESTNET_RPC_URLS: &[&str] = &["http://localhost:26657"]; const TENDERMINT_TEST_BIP39_SEED: &str = "emerge canoe salmon dolphin glow priority random become gasp sell blade argue"; +#[ignore] #[test] fn test_tendermint_balance() { let coins = json!([atom_testnet_conf()]); @@ -44,6 +45,7 @@ fn test_tendermint_balance() { assert_eq!(my_balance.coin, coin); } +#[ignore] #[test] fn test_tendermint_activation_without_balance() { let coins = json!([atom_testnet_conf()]); @@ -66,6 +68,7 @@ fn test_tendermint_activation_without_balance() { assert!(result.result.tokens_tickers.unwrap().is_empty()); } +#[ignore] #[test] fn test_iris_ibc_nucleus_without_balance() { let coins = json!([nucleus_testnet_conf(), iris_ibc_nucleus_testnet_conf()]); @@ -93,6 +96,7 @@ fn test_iris_ibc_nucleus_without_balance() { ); } +#[ignore] #[test] fn test_iris_ibc_nucleus_orderbook() { let coins = json!([nucleus_testnet_conf(), iris_ibc_nucleus_testnet_conf()]); @@ -141,6 +145,7 @@ fn test_iris_ibc_nucleus_orderbook() { assert_eq!(first_bid.entry.address, expected_address); } +#[ignore] #[test] fn test_tendermint_hd_address() { let coins = json!([atom_testnet_conf()]); @@ -157,6 +162,7 @@ fn test_tendermint_hd_address() { assert_eq!(result.result.address, expected_address); } +#[ignore] #[test] fn test_tendermint_withdraw() { const MY_ADDRESS: &str = "cosmos150evuj4j7k9kgu38e453jdv9m3u0ft2n53flg6"; @@ -214,6 +220,7 @@ fn test_tendermint_withdraw() { log!("Send raw tx {}", serde_json::to_string(&send_raw_tx).unwrap()); } +#[ignore] #[test] fn test_tendermint_withdraw_hd() { const MY_ADDRESS: &str = "cosmos134h9tv7866jcuw708w5w76lcfx7s3x2ysyalxy"; @@ -281,6 +288,7 @@ fn test_tendermint_withdraw_hd() { log!("Send raw tx {}", serde_json::to_string(&send_raw_tx).unwrap()); } +#[ignore] #[test] fn test_custom_gas_limit_on_tendermint_withdraw() { let coins = json!([atom_testnet_conf()]); @@ -311,6 +319,7 @@ fn test_custom_gas_limit_on_tendermint_withdraw() { assert_eq!(tx_details.fee_details["gas_limit"], 150000); } +#[ignore] #[test] fn test_tendermint_ibc_withdraw() { // visit `{swagger_address}/ibc/core/channel/v1/channels?pagination.limit=10000` to see the full list of ibc channels @@ -357,6 +366,7 @@ fn test_tendermint_ibc_withdraw() { log!("Send raw tx {}", serde_json::to_string(&send_raw_tx).unwrap()); } +#[ignore] #[test] fn test_tendermint_ibc_withdraw_hd() { // visit `{swagger_address}/ibc/core/channel/v1/channels?pagination.limit=10000` to see the full list of ibc channels @@ -404,6 +414,7 @@ fn test_tendermint_ibc_withdraw_hd() { log!("Send raw tx {}", serde_json::to_string(&send_raw_tx).unwrap()); } +#[ignore] #[test] fn test_tendermint_token_withdraw() { const MY_ADDRESS: &str = "nuc150evuj4j7k9kgu38e453jdv9m3u0ft2n4fgzfr"; @@ -484,6 +495,7 @@ fn test_tendermint_token_withdraw() { log!("Send raw tx {}", serde_json::to_string(&send_raw_tx).unwrap()); } +#[ignore] #[test] fn test_tendermint_tx_history() { const TEST_SEED: &str = "Vdo8Xt8pTAetRlMq3kV0LzE393eVYbPSn5Mhtw4p"; @@ -560,6 +572,7 @@ fn test_tendermint_tx_history() { block_on(mm.stop()).unwrap(); } +#[ignore] #[test] fn test_disable_tendermint_platform_coin_with_token() { let coins = json!([nucleus_testnet_conf(), iris_ibc_nucleus_testnet_conf()]); @@ -596,6 +609,7 @@ fn test_disable_tendermint_platform_coin_with_token() { assert!(!res.passivized); } +#[ignore] #[test] fn test_passive_coin_and_force_disable() { let coins = json!([nucleus_testnet_conf(), iris_ibc_nucleus_testnet_conf()]); @@ -672,6 +686,7 @@ mod swap { const BOB_PASSPHRASE: &str = "iris test seed"; const ALICE_PASSPHRASE: &str = "iris test2 seed"; + #[ignore] #[test] fn swap_nucleus_with_doc() { let bob_passphrase = String::from(BOB_PASSPHRASE); @@ -750,6 +765,7 @@ mod swap { )); } + #[ignore] #[test] fn swap_nucleus_with_eth() { let bob_passphrase = String::from(BOB_PASSPHRASE); @@ -856,6 +872,7 @@ mod swap { )); } + #[ignore] #[test] fn swap_doc_with_iris_ibc_nucleus() { let bob_passphrase = String::from(BOB_PASSPHRASE); diff --git a/mm2src/mm2_main/tests/docker_tests_main.rs b/mm2src/mm2_main/tests/docker_tests_main.rs index d9c64039a0..801e47eeb7 100644 --- a/mm2src/mm2_main/tests/docker_tests_main.rs +++ b/mm2src/mm2_main/tests/docker_tests_main.rs @@ -65,11 +65,11 @@ pub fn docker_tests_runner(tests: &[&TestDescAndFn]) { remove_docker_containers(image); } - let runtime_dir = prepare_runtime_dir().unwrap(); - - let nucleus_node = nucleus_node(&docker, runtime_dir.clone()); - let atom_node = atom_node(&docker, runtime_dir.clone()); - let ibc_relayer_node = ibc_relayer_node(&docker, runtime_dir); + // let runtime_dir = prepare_runtime_dir().unwrap(); + // + // let nucleus_node = nucleus_node(&docker, runtime_dir.clone()); + // let atom_node = atom_node(&docker, runtime_dir.clone()); + // let ibc_relayer_node = ibc_relayer_node(&docker, runtime_dir); let utxo_node = utxo_asset_docker_node(&docker, "MYCOIN", 7000); let utxo_node1 = utxo_asset_docker_node(&docker, "MYCOIN1", 8000); let qtum_node = qtum_docker_node(&docker, 9000); @@ -90,16 +90,16 @@ pub fn docker_tests_runner(tests: &[&TestDescAndFn]) { wait_for_geth_node_ready(); init_geth_node(); - wait_until_relayer_container_is_ready(ibc_relayer_node.container.id()); + // wait_until_relayer_container_is_ready(ibc_relayer_node.container.id()); containers.push(utxo_node); containers.push(utxo_node1); containers.push(qtum_node); containers.push(for_slp_node); containers.push(geth_node); - containers.push(nucleus_node); - containers.push(atom_node); - containers.push(ibc_relayer_node); + // containers.push(nucleus_node); + // containers.push(atom_node); + // containers.push(ibc_relayer_node); } // detect if docker is installed // skip the tests that use docker if not installed @@ -172,6 +172,7 @@ fn remove_docker_containers(name: &str) { .expect("Failed to execute docker command"); } } +#[allow(dead_code)] fn prepare_runtime_dir() -> std::io::Result { let project_root = { let mut current_dir = std::env::current_dir().unwrap(); From c7e01d53f00b9b26a3fbadf23fd395b8b300bf0e Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 22 Jul 2024 18:31:47 +0700 Subject: [PATCH 111/233] eth tpu v2 docker tests: balance check in send_and_refund_taker_funding_by_secret_eth --- .../tests/docker_tests/eth_docker_tests.rs | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index e2244c8c9b..0f8202ebb1 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -164,6 +164,18 @@ fn fill_erc20(to_addr: Address, amount: U256) { wait_for_confirmation(tx_hash); } +fn check_eth_balance(address: Address) -> U256 { + let _guard = GETH_NONCE_LOCK.lock().unwrap(); + block_on(GETH_WEB3.eth().balance(address, None)).unwrap() +} + +#[allow(dead_code)] +fn check_erc20_balance(address: Address) -> U256 { + let _guard = GETH_NONCE_LOCK.lock().unwrap(); + let erc20_contract = Contract::from_json(GETH_WEB3.eth(), erc20_contract(), ERC20_ABI.as_bytes()).unwrap(); + block_on(erc20_contract.query("balanceOf", (address,), None, Options::default(), None)).unwrap() +} + fn mint_erc721(to_addr: Address, token_id: U256) { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc721_contract = @@ -1533,6 +1545,11 @@ fn send_and_refund_taker_funding_by_secret_eth() { let funding_time_lock = now_sec() + 3000; let payment_time_lock = now_sec() + 1000; + let taker_address = block_on(taker_coin.my_addr()); + + let balance_before_payment = check_eth_balance(taker_address); + log!("Taker ETH balance before payment: {}", balance_before_payment); + let dex_fee = &DexFee::Standard("0.1".into()); let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); let payment_args = SendTakerFundingArgs { @@ -1552,11 +1569,14 @@ fn send_and_refund_taker_funding_by_secret_eth() { wait_for_confirmations(&taker_coin, &funding_tx, 60); + let balance_after_payment = check_eth_balance(taker_address); + log!("Taker ETH balance after payment: {}", balance_after_payment); + let refund_args = RefundFundingSecretArgs { funding_tx: &funding_tx, funding_time_lock, payment_time_lock, - maker_pubkey: &taker_coin.derive_htlc_pubkey_v2(&[]), + maker_pubkey: maker_pub, taker_secret: &taker_secret, taker_secret_hash: &taker_secret_hash, maker_secret_hash: &maker_secret_hash, @@ -1571,6 +1591,12 @@ fn send_and_refund_taker_funding_by_secret_eth() { "Taker refunded ETH funding by secret, tx hash: {:02x}", funding_tx_refund.tx_hash() ); + + wait_for_confirmations(&taker_coin, &funding_tx_refund, 60); + + let balance_after_refund = check_eth_balance(taker_address); + log!("Taker ETH balance after refund: {}", balance_after_refund); + assert_eq!(balance_before_payment, balance_after_refund); } #[test] From 8719922b71e4764887adf3a310004a2bae7185c5 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 22 Jul 2024 19:04:38 +0700 Subject: [PATCH 112/233] eth tpu v2 docker tests: balance check in refund by secret tests --- .../tests/docker_tests/eth_docker_tests.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 0f8202ebb1..5f148ed371 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -169,7 +169,6 @@ fn check_eth_balance(address: Address) -> U256 { block_on(GETH_WEB3.eth().balance(address, None)).unwrap() } -#[allow(dead_code)] fn check_erc20_balance(address: Address) -> U256 { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc20_contract = Contract::from_json(GETH_WEB3.eth(), erc20_contract(), ERC20_ABI.as_bytes()).unwrap(); @@ -1612,6 +1611,11 @@ fn send_and_refund_taker_funding_by_secret_erc20() { let funding_time_lock = now_sec() + 3000; let payment_time_lock = now_sec() + 1000; + let taker_address = block_on(taker_coin.my_addr()); + + let balance_before_payment = check_erc20_balance(taker_address); + log!("Taker ERC20 balance before payment: {}", balance_before_payment); + let dex_fee = &DexFee::Standard("0.1".into()); let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); let payment_args = SendTakerFundingArgs { @@ -1632,6 +1636,9 @@ fn send_and_refund_taker_funding_by_secret_erc20() { wait_for_confirmations(&taker_coin, &funding_tx, 60); + let balance_after_payment = check_eth_balance(taker_address); + log!("Taker ERC20 balance after payment: {}", balance_after_payment); + let refund_args = RefundFundingSecretArgs { funding_tx: &funding_tx, funding_time_lock, @@ -1651,6 +1658,11 @@ fn send_and_refund_taker_funding_by_secret_erc20() { "Taker refunded ERC20 funding by secret, tx hash: {:02x}", funding_tx_refund.tx_hash() ); + wait_for_confirmations(&taker_coin, &funding_tx_refund, 60); + + let balance_after_refund = check_eth_balance(taker_address); + log!("Taker ERC20 balance after refund: {}", balance_after_refund); + assert_eq!(balance_before_payment, balance_after_refund); } #[test] From a7974a95d447c5daaa93fc8603aa29fa5df9dcf4 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 22 Jul 2024 19:36:42 +0700 Subject: [PATCH 113/233] eth tpu v2 docker tests: add fill_erc20 --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 5f148ed371..c67407285a 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1529,6 +1529,7 @@ fn eth_coin_v2_activation_with_random_privkey(ticker: &str, conf: &Json, swap_ad .unwrap(); let my_address = block_on(coin.my_addr()); fill_eth(my_address, U256::from(10).pow(U256::from(20))); + fill_erc20(my_address, U256::from(10000000000u64)); coin } From 472c34b1bd7e9c68e7d3cc7e9a9d005f8023e3c5 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Jul 2024 12:12:35 +0700 Subject: [PATCH 114/233] eth tpu v2 docker tests: change sleep duration, add `wait_for_confirmations` for tx_refund in `funding_timelock` tests --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index c67407285a..d3b286b529 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1087,7 +1087,7 @@ fn test_nonce_lock() { #[test] fn send_and_refund_erc721_maker_payment_timelock() { - thread::sleep(Duration::from_secs(29)); + thread::sleep(Duration::from_secs(31)); let token_id = 2u32; let time_lock_to_refund = now_sec() - 1000; let activation = NftActivationV2Args::init(); @@ -1535,6 +1535,7 @@ fn eth_coin_v2_activation_with_random_privkey(ticker: &str, conf: &Json, swap_ad #[test] fn send_and_refund_taker_funding_by_secret_eth() { + thread::sleep(Duration::from_secs(3)); let taker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init()); let maker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init()); @@ -1601,6 +1602,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { #[test] fn send_and_refund_taker_funding_by_secret_erc20() { + thread::sleep(Duration::from_secs(7)); let erc20_conf = &erc20_dev_conf(&erc20_contract_checksum()); let taker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init()); let maker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init()); @@ -1720,10 +1722,13 @@ fn send_and_refund_taker_funding_timelock_eth() { "Taker refunded ETH funding after pre-approval lock time was exceeded, tx hash: {:02x}", funding_tx_refund.tx_hash() ); + + wait_for_confirmations(&taker_coin, &funding_tx_refund, 60); } #[test] fn send_and_refund_taker_funding_timelock_erc20() { + thread::sleep(Duration::from_secs(2)); let erc20_conf = &erc20_dev_conf(&erc20_contract_checksum()); let taker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init()); let maker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init()); @@ -1777,4 +1782,5 @@ fn send_and_refund_taker_funding_timelock_erc20() { "Taker refunded ERC20 funding after pre-approval lock time was exceeded, tx hash: {:02x}", funding_tx_refund.tx_hash() ); + wait_for_confirmations(&taker_coin, &funding_tx_refund, 60); } From 10b8f9b5afc2ec75e9ae19c114f1f26acc401da0 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Jul 2024 12:29:02 +0700 Subject: [PATCH 115/233] eth tpu v2 docker tests: change sleep duration, increase wait for conf in eth swap v2 --- .../tests/docker_tests/eth_docker_tests.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index d3b286b529..d1957c55f2 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1087,7 +1087,7 @@ fn test_nonce_lock() { #[test] fn send_and_refund_erc721_maker_payment_timelock() { - thread::sleep(Duration::from_secs(31)); + thread::sleep(Duration::from_secs(40)); let token_id = 2u32; let time_lock_to_refund = now_sec() - 1000; let activation = NftActivationV2Args::init(); @@ -1568,7 +1568,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 60); + wait_for_confirmations(&taker_coin, &funding_tx, 100); let balance_after_payment = check_eth_balance(taker_address); log!("Taker ETH balance after payment: {}", balance_after_payment); @@ -1593,7 +1593,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { funding_tx_refund.tx_hash() ); - wait_for_confirmations(&taker_coin, &funding_tx_refund, 60); + wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); let balance_after_refund = check_eth_balance(taker_address); log!("Taker ETH balance after refund: {}", balance_after_refund); @@ -1637,7 +1637,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ERC20 funding, tx hash {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 60); + wait_for_confirmations(&taker_coin, &funding_tx, 100); let balance_after_payment = check_eth_balance(taker_address); log!("Taker ERC20 balance after payment: {}", balance_after_payment); @@ -1661,7 +1661,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { "Taker refunded ERC20 funding by secret, tx hash: {:02x}", funding_tx_refund.tx_hash() ); - wait_for_confirmations(&taker_coin, &funding_tx_refund, 60); + wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); let balance_after_refund = check_eth_balance(taker_address); log!("Taker ERC20 balance after refund: {}", balance_after_refund); @@ -1699,7 +1699,7 @@ fn send_and_refund_taker_funding_timelock_eth() { let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 60); + wait_for_confirmations(&taker_coin, &funding_tx, 100); let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash: &maker_secret_hash, @@ -1723,7 +1723,7 @@ fn send_and_refund_taker_funding_timelock_eth() { funding_tx_refund.tx_hash() ); - wait_for_confirmations(&taker_coin, &funding_tx_refund, 60); + wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } #[test] @@ -1759,7 +1759,7 @@ fn send_and_refund_taker_funding_timelock_erc20() { let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 60); + wait_for_confirmations(&taker_coin, &funding_tx, 100); let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash: &maker_secret_hash, @@ -1782,5 +1782,5 @@ fn send_and_refund_taker_funding_timelock_erc20() { "Taker refunded ERC20 funding after pre-approval lock time was exceeded, tx hash: {:02x}", funding_tx_refund.tx_hash() ); - wait_for_confirmations(&taker_coin, &funding_tx_refund, 60); + wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } From dc215ec1b19e4e120d502c1b02365ae829fe33e4 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Jul 2024 12:41:34 +0700 Subject: [PATCH 116/233] ignore tendermint tests --- mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs | 3 +++ mm2src/mm2_main/tests/docker_tests_main.rs | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index cc1790cb0a..09e6b1d5ef 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -110,8 +110,11 @@ pub const UTXO_ASSET_DOCKER_IMAGE_WITH_TAG: &str = "docker.io/artempikulin/testb pub const GETH_DOCKER_IMAGE: &str = "docker.io/ethereum/client-go"; pub const GETH_DOCKER_IMAGE_WITH_TAG: &str = "docker.io/ethereum/client-go:stable"; +#[allow(dead_code)] pub const NUCLEUS_IMAGE: &str = "docker.io/komodoofficial/nucleusd"; +#[allow(dead_code)] pub const ATOM_IMAGE: &str = "docker.io/komodoofficial/gaiad"; +#[allow(dead_code)] pub const IBC_RELAYER_IMAGE: &str = "docker.io/komodoofficial/ibc-relayer"; pub const QTUM_ADDRESS_LABEL: &str = "MM2_ADDRESS_LABEL"; diff --git a/mm2src/mm2_main/tests/docker_tests_main.rs b/mm2src/mm2_main/tests/docker_tests_main.rs index 801e47eeb7..abbed46224 100644 --- a/mm2src/mm2_main/tests/docker_tests_main.rs +++ b/mm2src/mm2_main/tests/docker_tests_main.rs @@ -55,9 +55,9 @@ pub fn docker_tests_runner(tests: &[&TestDescAndFn]) { UTXO_ASSET_DOCKER_IMAGE_WITH_TAG, QTUM_REGTEST_DOCKER_IMAGE_WITH_TAG, GETH_DOCKER_IMAGE_WITH_TAG, - NUCLEUS_IMAGE, - ATOM_IMAGE, - IBC_RELAYER_IMAGE, + // NUCLEUS_IMAGE, + // ATOM_IMAGE, + // IBC_RELAYER_IMAGE, ]; for image in IMAGES { From 787a2b2d6ee159bc6b29f30f76883b59d4caf161 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Jul 2024 12:46:29 +0700 Subject: [PATCH 117/233] ignore nft, eth docker tests --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index d1957c55f2..e6a680d583 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -671,11 +671,13 @@ fn send_and_refund_eth_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { assert_eq!(expected, search_tx); } +#[ignore] #[test] fn send_and_refund_eth_maker_payment_internal_gas_policy() { send_and_refund_eth_maker_payment_impl(SwapTxFeePolicy::Internal); } +#[ignore] #[test] fn send_and_refund_eth_maker_payment_priority_fee() { send_and_refund_eth_maker_payment_impl(SwapTxFeePolicy::Medium); } @@ -756,11 +758,13 @@ fn send_and_spend_eth_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { assert_eq!(expected, search_tx); } +#[ignore] #[test] fn send_and_spend_eth_maker_payment_internal_gas_policy() { send_and_spend_eth_maker_payment_impl(SwapTxFeePolicy::Internal); } +#[ignore] #[test] fn send_and_spend_eth_maker_payment_priority_fee() { send_and_spend_eth_maker_payment_impl(SwapTxFeePolicy::Medium); } @@ -973,6 +977,7 @@ fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option Date: Tue, 23 Jul 2024 14:17:56 +0700 Subject: [PATCH 118/233] add balance checks --- .../tests/docker_tests/eth_docker_tests.rs | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index e6a680d583..aefe7cae65 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1649,7 +1649,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { wait_for_confirmations(&taker_coin, &funding_tx, 100); - let balance_after_payment = check_eth_balance(taker_address); + let balance_after_payment = check_erc20_balance(taker_address); log!("Taker ERC20 balance after payment: {}", balance_after_payment); let refund_args = RefundFundingSecretArgs { @@ -1673,7 +1673,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { ); wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); - let balance_after_refund = check_eth_balance(taker_address); + let balance_after_refund = check_erc20_balance(taker_address); log!("Taker ERC20 balance after refund: {}", balance_after_refund); assert_eq!(balance_before_payment, balance_after_refund); } @@ -1687,6 +1687,12 @@ fn send_and_refund_taker_funding_timelock_eth() { let taker_secret_hash = sha256(&taker_secret).to_vec(); let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); + + let taker_address = block_on(taker_coin.my_addr()); + + let balance_before_payment = check_eth_balance(taker_address); + log!("Taker ETH balance before payment: {}", balance_before_payment); + // exceed funding_time_lock, as if TakerPaymentState.PaymentSent then timestamp should exceed payment pre-approve lock time let funding_time_lock = now_sec() - 3000; // TODO need to impl taker approve to test exceeded payment_time_lock @@ -1711,6 +1717,9 @@ fn send_and_refund_taker_funding_timelock_eth() { wait_for_confirmations(&taker_coin, &funding_tx, 100); + let balance_after_payment = check_eth_balance(taker_address); + log!("Taker ETH balance after payment: {}", balance_after_payment); + let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash: &maker_secret_hash, taker_secret_hash: &taker_secret_hash, @@ -1734,6 +1743,10 @@ fn send_and_refund_taker_funding_timelock_eth() { ); wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); + + let balance_after_refund = check_eth_balance(taker_address); + log!("Taker ETH balance after refund: {}", balance_after_refund); + assert_eq!(balance_before_payment, balance_after_refund); } #[test] @@ -1747,6 +1760,12 @@ fn send_and_refund_taker_funding_timelock_erc20() { let taker_secret_hash = sha256(&taker_secret).to_vec(); let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); + + let taker_address = block_on(taker_coin.my_addr()); + + let balance_before_payment = check_erc20_balance(taker_address); + log!("Taker ERC20 balance before payment: {}", balance_before_payment); + // exceed funding_time_lock, as if TakerPaymentState.PaymentSent then timestamp should exceed payment pre-approve lock time let funding_time_lock = now_sec() - 3000; // TODO need to impl taker approve to test exceeded payment_time_lock @@ -1771,6 +1790,9 @@ fn send_and_refund_taker_funding_timelock_erc20() { wait_for_confirmations(&taker_coin, &funding_tx, 100); + let balance_after_payment = check_erc20_balance(taker_address); + log!("Taker ERC20 balance after payment: {}", balance_after_payment); + let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash: &maker_secret_hash, taker_secret_hash: &taker_secret_hash, @@ -1793,4 +1815,8 @@ fn send_and_refund_taker_funding_timelock_erc20() { funding_tx_refund.tx_hash() ); wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); + + let balance_after_refund = check_erc20_balance(taker_address); + log!("Taker ERC20 balance after refund: {}", balance_after_refund); + assert_eq!(balance_before_payment, balance_after_refund); } From 351d5383ef161ea5c332bce460b78cfefd9afbbc Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Jul 2024 14:29:59 +0700 Subject: [PATCH 119/233] ignore timelock and leave refund by secret --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index aefe7cae65..55f9272f43 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1545,7 +1545,7 @@ fn eth_coin_v2_activation_with_random_privkey(ticker: &str, conf: &Json, swap_ad #[test] fn send_and_refund_taker_funding_by_secret_eth() { - thread::sleep(Duration::from_secs(3)); + thread::sleep(Duration::from_secs(1)); let taker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init()); let maker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init()); @@ -1612,7 +1612,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { #[test] fn send_and_refund_taker_funding_by_secret_erc20() { - thread::sleep(Duration::from_secs(7)); + thread::sleep(Duration::from_secs(3)); let erc20_conf = &erc20_dev_conf(&erc20_contract_checksum()); let taker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init()); let maker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init()); @@ -1678,6 +1678,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { assert_eq!(balance_before_payment, balance_after_refund); } +#[ignore] #[test] fn send_and_refund_taker_funding_timelock_eth() { let taker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init()); @@ -1749,6 +1750,7 @@ fn send_and_refund_taker_funding_timelock_eth() { assert_eq!(balance_before_payment, balance_after_refund); } +#[ignore] #[test] fn send_and_refund_taker_funding_timelock_erc20() { thread::sleep(Duration::from_secs(2)); From e0e91269e458377d1f04d43fe767e87fd4a1c5c0 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Jul 2024 15:17:19 +0700 Subject: [PATCH 120/233] more logs, add dexFee to eth_total_payment --- mm2src/coins/eth.rs | 7 ++++--- mm2src/coins/eth/eth_swap_v2.rs | 18 +++++++++++++++--- .../tests/docker_tests/eth_docker_tests.rs | 6 +++++- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 8ac534a3ec..a87878e2ff 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7080,8 +7080,9 @@ impl TakerCoinSwapOpsV2 for EthCoin { self.send_taker_funding_impl(args).await } - async fn validate_taker_funding(&self, _args: ValidateTakerFundingArgs<'_, Self>) -> ValidateSwapV2TxResult { - todo!() + /// Validates sent taker payment + async fn validate_taker_funding(&self, args: ValidateTakerFundingArgs<'_, Self>) -> ValidateSwapV2TxResult { + self.validate_taker_funding_impl(args).await } async fn refund_taker_funding_timelock( @@ -7098,7 +7099,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { self.refund_taker_funding_secret_impl(args).await } - /// checks taker payment status in etomic swap contract + /// Checks taker payment status in etomic swap contract async fn search_for_taker_funding_spend( &self, _tx: &Self::Tx, diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 9c3df60f49..0ad843ae3c 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,6 +1,6 @@ use super::eth::{wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; use super::{RefundFundingSecretArgs, RefundTakerPaymentArgs, SendTakerFundingArgs, SwapTxTypeWithSecretHash, - Transaction, TransactionErr}; + Transaction, TransactionErr, ValidateSwapV2TxResult, ValidateTakerFundingArgs}; use bitcrypto::sha256; use enum_derives::EnumFromStringify; use ethabi::Token; @@ -53,7 +53,11 @@ impl EthCoin { let dex_fee = try_tx_s!(wei_from_big_decimal(&args.dex_fee.fee_amount().into(), self.decimals)); let payment_amount = try_tx_s!(wei_from_big_decimal( - &(args.trading_amount + args.premium_amount), + &(args.trading_amount.clone() + args.premium_amount.clone()), + self.decimals + )); + let eth_total_payment = try_tx_s!(wei_from_big_decimal( + &(args.dex_fee.fee_amount().to_decimal() + args.trading_amount + args.premium_amount), self.decimals )); // TODO add maker_pub created by legacy derive_htlc_pubkey support additionally? @@ -76,7 +80,7 @@ impl EthCoin { EthCoinType::Eth => { let data = try_tx_s!(self.prepare_taker_eth_funding_data(&funding_args).await); self.sign_and_send_transaction( - payment_amount, + eth_total_payment, Action::Call(taker_swap_v2_contract), data, U256::from(self.gas_limit.eth_payment), @@ -95,6 +99,7 @@ impl EthCoin { .map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?; let data = try_tx_s!(self.prepare_taker_erc20_funding_data(&funding_args, *token_addr).await); if allowed < payment_amount { + println!("Allowed: {}, payment_amount: {}", allowed, payment_amount); let approved_tx = self.approve(taker_swap_v2_contract, U256::max_value()).compat().await?; self.wait_for_required_allowance( taker_swap_v2_contract, @@ -135,6 +140,13 @@ impl EthCoin { } } + pub(crate) async fn validate_taker_funding_impl( + &self, + _args: ValidateTakerFundingArgs<'_, Self>, + ) -> ValidateSwapV2TxResult { + todo!() + } + pub(crate) async fn refund_taker_funding_timelock_impl( &self, args: RefundTakerPaymentArgs<'_>, diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 55f9272f43..e5c7072ab8 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1628,6 +1628,8 @@ fn send_and_refund_taker_funding_by_secret_erc20() { let balance_before_payment = check_erc20_balance(taker_address); log!("Taker ERC20 balance before payment: {}", balance_before_payment); + let eth_before_payment = check_eth_balance(taker_address); + log!("Taker ETH balance before payment: {}", eth_before_payment); let dex_fee = &DexFee::Standard("0.1".into()); let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); @@ -1641,7 +1643,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { premium_amount: BigDecimal::default(), trading_amount: 1.into(), swap_unique_data: &[], - wait_for_confirmation_until: now_sec() + 60, + wait_for_confirmation_until: now_sec() + 80, }; let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); @@ -1651,6 +1653,8 @@ fn send_and_refund_taker_funding_by_secret_erc20() { let balance_after_payment = check_erc20_balance(taker_address); log!("Taker ERC20 balance after payment: {}", balance_after_payment); + let eth_after_payment = check_eth_balance(taker_address); + log!("Taker ETH balance after payment: {}", eth_after_payment); let refund_args = RefundFundingSecretArgs { funding_tx: &funding_tx, From f2ac7ef77286b2138aa71e129bc2e34831579d0a Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Jul 2024 15:37:15 +0700 Subject: [PATCH 121/233] update taker_swap_v2_bytes --- mm2src/coins/eth/eth_swap_v2.rs | 2 +- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 2 ++ mm2src/mm2_test_helpers/contract_bytes/taker_swap_v2_bytes | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 0ad843ae3c..d4b0955689 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -99,7 +99,7 @@ impl EthCoin { .map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?; let data = try_tx_s!(self.prepare_taker_erc20_funding_data(&funding_args, *token_addr).await); if allowed < payment_amount { - println!("Allowed: {}, payment_amount: {}", allowed, payment_amount); + log!("Allowed: {}, payment_amount: {}", allowed, payment_amount); let approved_tx = self.approve(taker_swap_v2_contract, U256::max_value()).compat().await?; self.wait_for_required_allowance( taker_swap_v2_contract, diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index e5c7072ab8..7b43219162 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1625,6 +1625,8 @@ fn send_and_refund_taker_funding_by_secret_erc20() { let payment_time_lock = now_sec() + 1000; let taker_address = block_on(taker_coin.my_addr()); + log!("taker_address type: {:?}", taker_address); + log!("coin type: {:?}", taker_coin.coin_type); let balance_before_payment = check_erc20_balance(taker_address); log!("Taker ERC20 balance before payment: {}", balance_before_payment); diff --git a/mm2src/mm2_test_helpers/contract_bytes/taker_swap_v2_bytes b/mm2src/mm2_test_helpers/contract_bytes/taker_swap_v2_bytes index 25960a6cc5..59e2a32f59 100644 --- a/mm2src/mm2_test_helpers/contract_bytes/taker_swap_v2_bytes +++ b/mm2src/mm2_test_helpers/contract_bytes/taker_swap_v2_bytes @@ -1 +1 @@ -60a060405234801561000f575f80fd5b50604051612a1b380380612a1b83398181016040528101906100319190610137565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361009f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610096906101e2565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505050610200565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610106826100dd565b9050919050565b610116816100fc565b8114610120575f80fd5b50565b5f815190506101318161010d565b92915050565b5f6020828403121561014c5761014b6100d9565b5b5f61015984828501610123565b91505092915050565b5f82825260208201905092915050565b7f66656541646472657373206d757374206e6f74206265207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f6101cc602383610162565b91506101d782610172565b604082019050919050565b5f6020820190508181035f8301526101f9816101c0565b9050919050565b6080516127f56102265f395f818161116d0152818161120801526115c401526127f55ff3fe60806040526004361061007a575f3560e01c80639b4603f21161004d5780639b4603f214610135578063cc90c19914610151578063d6a71eb414610179578063e06cf966146101a15761007a565b8063146e5b241461007e5780633e6af5f2146100a657806346b95ac7146100ce57806365e266171461010d575b5f80fd5b348015610089575f80fd5b506100a4600480360381019061009f91906119ef565b6101cb565b005b3480156100b1575f80fd5b506100cc60048036038101906100c791906119ef565b6103ae565b005b3480156100d9575f80fd5b506100f460048036038101906100ef9190611a8c565b6106bc565b6040516101049493929190611b82565b60405180910390f35b348015610118575f80fd5b50610133600480360381019061012e91906119ef565b61071d565b005b61014f600480360381019061014a9190611bef565b610b79565b005b34801561015c575f80fd5b50610177600480360381019061017291906119ef565b610ead565b005b348015610184575f80fd5b5061019f600480360381019061019a9190611c8c565b61125a565b005b3480156101ac575f80fd5b506101b56115c2565b6040516101c29190611d5f565b60405180910390f35b600160048111156101df576101de611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff16600481111561021157610210611b0f565b5b14610251576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024890611df8565b60405180910390fd5b5f6003878787338888886040516020016102719796959493929190611e9b565b60405160208183030381529060405260405161028d9190611f6d565b602060405180830381855afa1580156102a8573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610332576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032990611fcd565b60405180910390fd5b60025f808a81526020019081526020015f205f01601c6101000a81548160ff0219169083600481111561036857610367611b0f565b5b02179055507f9c45e43e2ef051f70491ffd5221bf02ab37e1324128714ef9610df5f24fc9fb58860405161039c9190611ffa565b60405180910390a15050505050505050565b600160048111156103c2576103c1611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660048111156103f4576103f3611b0f565b5b14610434576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042b90611df8565b60405180910390fd5b5f60038787873360028960405160200161044e9190612013565b60405160208183030381529060405260405161046a9190611f6d565b602060405180830381855afa158015610485573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906104a89190612041565b88886040516020016104c09796959493929190611e9b565b6040516020818303038152906040526040516104dc9190611f6d565b602060405180830381855afa1580156104f7573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610581576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057890611fcd565b60405180910390fd5b60045f808a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156105b7576105b6611b0f565b5b02179055507f45169a52eef651b20a81474b50b8a5d83225225fcd097ef3cf7952d9ab304f2788856040516105ed92919061206c565b60405180910390a15f868861060291906120c0565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610680573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f1935050505015801561067a573d5f803e3d5ffd5b506106b1565b5f8390506106af33838373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900463ffffffff1690805f01601c9054906101000a900460ff16905084565b6001600481111561073157610730611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff16600481111561076357610762611b0f565b5b14806107b257506002600481111561077e5761077d611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660048111156107b0576107af611b0f565b5b145b6107f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e890612163565b60405180910390fd5b5f6003878787338888886040516020016108119796959493929190611e9b565b60405160208183030381529060405260405161082d9190611f6d565b602060405180830381855afa158015610848573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146108d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c990611fcd565b60405180910390fd5b600260048111156108e6576108e5611b0f565b5b5f808a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561091857610917611b0f565b5b03610989575f808981526020019081526020015f205f0160189054906101000a900463ffffffff1663ffffffff16421015610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097f906121f1565b60405180910390fd5b5b6001600481111561099d5761099c611b0f565b5b5f808a81526020019081526020015f205f01601c9054906101000a900460ff1660048111156109cf576109ce611b0f565b5b03610a40575f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff16421015610a3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a369061227f565b60405180910390fd5b5b60045f808a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610a7657610a75611b0f565b5b02179055507fbdd7a4be6d82798a500b59077706b12d3f45acf5504828919f92501307b2b95388604051610aaa9190611ffa565b60405180910390a15f8688610abf91906120c0565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b3d573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015610b37573d5f803e3d5ffd5b50610b6e565b5f839050610b6c33838373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b505050505050505050565b5f6004811115610b8c57610b8b611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff166004811115610bbe57610bbd611b0f565b5b14610bfe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf59061230d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610c6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c639061239b565b60405180910390fd5b5f3411610cae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca590612429565b60405180910390fd5b853411610cf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce7906124b7565b60405180910390fd5b5f60038734610cff91906124d5565b88883389895f604051602001610d1b9796959493929190611e9b565b604051602081830303815290604052604051610d379190611f6d565b602060405180830381855afa158015610d52573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115610daa57610da9611b0f565b5b8152505f808a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115610e6457610e63611b0f565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd93588604051610e9b9190611ffa565b60405180910390a15050505050505050565b60026004811115610ec157610ec0611b0f565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff166004811115610ef357610ef2611b0f565b5b14610f33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2a90612578565b60405180910390fd5b5f60038787338888600289604051602001610f4e9190612013565b604051602081830303815290604052604051610f6a9190611f6d565b602060405180830381855afa158015610f85573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610fa89190612041565b88604051602001610fbf9796959493929190611e9b565b604051602081830303815290604052604051610fdb9190611f6d565b602060405180830381855afa158015610ff6573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611080576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107790611fcd565b60405180910390fd5b60035f808a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156110b6576110b5611b0f565b5b02179055507f0d0da0df275f85bed3a5fe7ae79f3559341a3f9ccd8e010133438135bda00a8788846040516110ec92919061206c565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111d4573373ffffffffffffffffffffffffffffffffffffffff166108fc8890811502906040515f60405180830381858888f1935050505015801561116a573d5f803e3d5ffd5b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f193505050501580156111ce573d5f803e3d5ffd5b50611250565b5f82905061120333898373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b61124e7f0000000000000000000000000000000000000000000000000000000000000000888373ffffffffffffffffffffffffffffffffffffffff166115e69092919063ffffffff16565b505b5050505050505050565b5f600481111561126d5761126c611b0f565b5b5f808b81526020019081526020015f205f01601c9054906101000a900460ff16600481111561129f5761129e611b0f565b5b146112df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d690612606565b60405180910390fd5b5f8811611321576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113189061266e565b60405180910390fd5b5f8711611363576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135a906126d6565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c89061239b565b60405180910390fd5b5f60038989883389898d6040516020016113f19796959493929190611e9b565b60405160208183030381529060405260405161140d9190611f6d565b602060405180830381855afa158015611428573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff168152602001600160048111156114805761147f611b0f565b5b8152505f808c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff0219169083600481111561153a57611539611b0f565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358a6040516115719190611ffa565b60405180910390a15f8790506115b533308b8d61158e91906120c0565b8473ffffffffffffffffffffffffffffffffffffffff16611665909392919063ffffffff16565b5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b611660838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401611619929190612703565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506116e7565b505050565b6116e1848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161169a9392919061272a565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506116e7565b50505050565b5f611711828473ffffffffffffffffffffffffffffffffffffffff1661177c90919063ffffffff16565b90505f8151141580156117355750808060200190518101906117339190612794565b155b1561177757826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161176e9190611d5f565b60405180910390fd5b505050565b606061178983835f611791565b905092915050565b6060814710156117d857306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016117cf9190611d5f565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516118009190611f6d565b5f6040518083038185875af1925050503d805f811461183a576040519150601f19603f3d011682016040523d82523d5f602084013e61183f565b606091505b509150915061184f86838361185a565b925050509392505050565b60608261186f5761186a826118e7565b6118df565b5f825114801561189557505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156118d757836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016118ce9190611d5f565b60405180910390fd5b8190506118e0565b5b9392505050565b5f815111156118f95780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80fd5b5f819050919050565b6119418161192f565b811461194b575f80fd5b50565b5f8135905061195c81611938565b92915050565b5f819050919050565b61197481611962565b811461197e575f80fd5b50565b5f8135905061198f8161196b565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6119be82611995565b9050919050565b6119ce816119b4565b81146119d8575f80fd5b50565b5f813590506119e9816119c5565b92915050565b5f805f805f805f60e0888a031215611a0a57611a0961192b565b5b5f611a178a828b0161194e565b9750506020611a288a828b01611981565b9650506040611a398a828b01611981565b9550506060611a4a8a828b016119db565b9450506080611a5b8a828b0161194e565b93505060a0611a6c8a828b0161194e565b92505060c0611a7d8a828b016119db565b91505092959891949750929550565b5f60208284031215611aa157611aa061192b565b5b5f611aae8482850161194e565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b611aeb81611ab7565b82525050565b5f63ffffffff82169050919050565b611b0981611af1565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60058110611b4d57611b4c611b0f565b5b50565b5f819050611b5d82611b3c565b919050565b5f611b6c82611b50565b9050919050565b611b7c81611b62565b82525050565b5f608082019050611b955f830187611ae2565b611ba26020830186611b00565b611baf6040830185611b00565b611bbc6060830184611b73565b95945050505050565b611bce81611af1565b8114611bd8575f80fd5b50565b5f81359050611be981611bc5565b92915050565b5f805f805f805f60e0888a031215611c0a57611c0961192b565b5b5f611c178a828b0161194e565b9750506020611c288a828b01611981565b9650506040611c398a828b016119db565b9550506060611c4a8a828b0161194e565b9450506080611c5b8a828b0161194e565b93505060a0611c6c8a828b01611bdb565b92505060c0611c7d8a828b01611bdb565b91505092959891949750929550565b5f805f805f805f805f6101208a8c031215611caa57611ca961192b565b5b5f611cb78c828d0161194e565b9950506020611cc88c828d01611981565b9850506040611cd98c828d01611981565b9750506060611cea8c828d016119db565b9650506080611cfb8c828d016119db565b95505060a0611d0c8c828d0161194e565b94505060c0611d1d8c828d0161194e565b93505060e0611d2e8c828d01611bdb565b925050610100611d408c828d01611bdb565b9150509295985092959850929598565b611d59816119b4565b82525050565b5f602082019050611d725f830184611d50565b92915050565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f611de2602a83611d78565b9150611ded82611d88565b604082019050919050565b5f6020820190508181035f830152611e0f81611dd6565b9050919050565b5f819050919050565b611e30611e2b82611962565b611e16565b82525050565b5f8160601b9050919050565b5f611e4c82611e36565b9050919050565b5f611e5d82611e42565b9050919050565b611e75611e70826119b4565b611e53565b82525050565b5f819050919050565b611e95611e908261192f565b611e7b565b82525050565b5f611ea6828a611e1f565b602082019150611eb68289611e1f565b602082019150611ec68288611e64565b601482019150611ed68287611e64565b601482019150611ee68286611e84565b602082019150611ef68285611e84565b602082019150611f068284611e64565b60148201915081905098975050505050505050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f611f4782611f1b565b611f518185611f25565b9350611f61818560208601611f2f565b80840191505092915050565b5f611f788284611f3d565b915081905092915050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f611fb7601383611d78565b9150611fc282611f83565b602082019050919050565b5f6020820190508181035f830152611fe481611fab565b9050919050565b611ff48161192f565b82525050565b5f60208201905061200d5f830184611feb565b92915050565b5f61201e8284611e84565b60208201915081905092915050565b5f8151905061203b81611938565b92915050565b5f602082840312156120565761205561192b565b5b5f6120638482850161202d565b91505092915050565b5f60408201905061207f5f830185611feb565b61208c6020830184611feb565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6120ca82611962565b91506120d583611962565b92508282019050808211156120ed576120ec612093565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e74206f722054616b6572417070726f7665640000000000602082015250565b5f61214d603b83611d78565b9150612158826120f3565b604082019050919050565b5f6020820190508181035f83015261217a81612141565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f6121db603883611d78565b91506121e682612181565b604082019050919050565b5f6020820190508181035f830152612208816121cf565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e74207072652d617070726f7665206c6f636b2074696d65000000602082015250565b5f612269603d83611d78565b91506122748261220f565b604082019050919050565b5f6020820190508181035f8301526122968161225d565b9050919050565b7f54616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f6122f7602483611d78565b91506123028261229d565b604082019050919050565b5f6020820190508181035f830152612324816122eb565b9050919050565b7f5265636569766572206d757374206e6f74206265207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f612385602183611d78565b91506123908261232b565b604082019050919050565b5f6020820190508181035f8301526123b281612379565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f612413602383611d78565b915061241e826123b9565b604082019050919050565b5f6020820190508181035f83015261244081612407565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e20645f8201527f6578206665650000000000000000000000000000000000000000000000000000602082015250565b5f6124a1602683611d78565b91506124ac82612447565b604082019050919050565b5f6020820190508181035f8301526124ce81612495565b9050919050565b5f6124df82611962565b91506124ea83611962565b925082820390508181111561250257612501612093565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520545f8201527f616b6572417070726f7665640000000000000000000000000000000000000000602082015250565b5f612562602c83611d78565b915061256d82612508565b604082019050919050565b5f6020820190508181035f83015261258f81612556565b9050919050565b7f4552433230207632207061796d656e7420697320616c726561647920696e69745f8201527f69616c697a656400000000000000000000000000000000000000000000000000602082015250565b5f6125f0602783611d78565b91506125fb82612596565b604082019050919050565b5f6020820190508181035f83015261261d816125e4565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f612658601783611d78565b915061266382612624565b602082019050919050565b5f6020820190508181035f8301526126858161264c565b9050919050565b7f44657820666565206d757374206e6f74206265207a65726f00000000000000005f82015250565b5f6126c0601883611d78565b91506126cb8261268c565b602082019050919050565b5f6020820190508181035f8301526126ed816126b4565b9050919050565b6126fd81611962565b82525050565b5f6040820190506127165f830185611d50565b61272360208301846126f4565b9392505050565b5f60608201905061273d5f830186611d50565b61274a6020830185611d50565b61275760408301846126f4565b949350505050565b5f8115159050919050565b6127738161275f565b811461277d575f80fd5b50565b5f8151905061278e8161276a565b92915050565b5f602082840312156127a9576127a861192b565b5b5f6127b684828501612780565b9150509291505056fea2646970667358221220fdfd279e725ae77372fd2984ed85918b447664a0bbfc3fa6036a0cb26bbaf52264736f6c634300081a0033 \ No newline at end of file +60a060405234801561000f575f80fd5b50604051613ffe380380613ffe83398181016040528101906100319190610137565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361009f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610096906101e2565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505050610200565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610106826100dd565b9050919050565b610116816100fc565b8114610120575f80fd5b50565b5f815190506101318161010d565b92915050565b5f6020828403121561014c5761014b6100d9565b5b5f61015984828501610123565b91505092915050565b5f82825260208201905092915050565b7f66656541646472657373206d757374206e6f74206265207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f6101cc602383610162565b91506101d782610172565b604082019050919050565b5f6020820190508181035f8301526101f9816101c0565b9050919050565b608051613dd86102265f395f818161182b015281816118c60152611c820152613dd85ff3fe6080604052600436106100a6575f3560e01c80639b4603f2116100635780639b4603f2146101d9578063bc197c81146101f5578063cc90c19914610231578063d6a71eb414610259578063e06cf96614610281578063f23a6e61146102ab576100a6565b806301ffc9a7146100aa578063146e5b24146100e6578063150b7a021461010e5780633e6af5f21461014a57806346b95ac71461017257806365e26617146101b1575b5f80fd5b3480156100b5575f80fd5b506100d060048036038101906100cb9190612593565b6102e7565b6040516100dd91906125d8565b60405180910390f35b3480156100f1575f80fd5b5061010c600480360381019061010791906126b1565b6103c8565b005b348015610119575f80fd5b50610134600480360381019061012f91906127af565b6105ab565b6040516101419190612842565b60405180910390f35b348015610155575f80fd5b50610170600480360381019061016b91906126b1565b610a30565b005b34801561017d575f80fd5b506101986004803603810190610193919061285b565b610d3e565b6040516101a89493929190612951565b60405180910390f35b3480156101bc575f80fd5b506101d760048036038101906101d291906126b1565b610d9f565b005b6101f360048036038101906101ee91906129be565b6111fb565b005b348015610200575f80fd5b5061021b60048036038101906102169190612ab0565b61152f565b6040516102289190612842565b60405180910390f35b34801561023c575f80fd5b50610257600480360381019061025291906126b1565b61156b565b005b348015610264575f80fd5b5061027f600480360381019061027a9190612b87565b611918565b005b34801561028c575f80fd5b50610295611c80565b6040516102a29190612c5a565b60405180910390f35b3480156102b6575f80fd5b506102d160048036038101906102cc9190612c73565b611ca4565b6040516102de9190612842565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103b157507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103c157506103c08261216e565b5b9050919050565b600160048111156103dc576103db6128de565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff16600481111561040e5761040d6128de565b5b1461044e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161044590612d89565b60405180910390fd5b5f60038787873388888860405160200161046e9796959493929190612e2c565b60405160208183030381529060405260405161048a9190612efe565b602060405180830381855afa1580156104a5573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461052f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052690612f5e565b60405180910390fd5b60025f808a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610565576105646128de565b5b02179055507f9c45e43e2ef051f70491ffd5221bf02ab37e1324128714ef9610df5f24fc9fb5886040516105999190612f8b565b60405180910390a15050505050505050565b5f8083838101906105bc91906130cd565b90505f60048111156105d1576105d06128de565b5b5f80835f015181526020019081526020015f205f01601c9054906101000a900460ff166004811115610606576106056128de565b5b14610646576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161063d90613168565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff16036106b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106af906131d0565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff160361072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072190613238565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461079c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610793906132c6565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161461080a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108019061332e565b60405180910390fd5b61081781602001516121d7565b15610857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084e90613396565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610885969594939291906133b4565b6040516020818303038152906040526040516108a19190612efe565b602060405180830381855afa1580156108bc573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020018360a0015163ffffffff1681526020016001600481111561091c5761091b6128de565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff021916908360048111156109d9576109d86128de565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd935825f0151604051610a139190612f8b565b60405180910390a163150b7a0260e01b9250505095945050505050565b60016004811115610a4457610a436128de565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff166004811115610a7657610a756128de565b5b14610ab6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aad90612d89565b60405180910390fd5b5f600387878733600289604051602001610ad09190613423565b604051602081830303815290604052604051610aec9190612efe565b602060405180830381855afa158015610b07573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610b2a9190613451565b8888604051602001610b429796959493929190612e2c565b604051602081830303815290604052604051610b5e9190612efe565b602060405180830381855afa158015610b79573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610c03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bfa90612f5e565b60405180910390fd5b60045f808a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610c3957610c386128de565b5b02179055507f45169a52eef651b20a81474b50b8a5d83225225fcd097ef3cf7952d9ab304f278885604051610c6f92919061347c565b60405180910390a15f8688610c8491906134d0565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610d02573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015610cfc573d5f803e3d5ffd5b50610d33565b5f839050610d3133838373ffffffffffffffffffffffffffffffffffffffff166121e89092919063ffffffff16565b505b505050505050505050565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900463ffffffff1690805f01601c9054906101000a900460ff16905084565b60016004811115610db357610db26128de565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff166004811115610de557610de46128de565b5b1480610e34575060026004811115610e0057610dff6128de565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff166004811115610e3257610e316128de565b5b145b610e73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6a90613573565b60405180910390fd5b5f600387878733888888604051602001610e939796959493929190612e2c565b604051602081830303815290604052604051610eaf9190612efe565b602060405180830381855afa158015610eca573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610f54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4b90612f5e565b60405180910390fd5b60026004811115610f6857610f676128de565b5b5f808a81526020019081526020015f205f01601c9054906101000a900460ff166004811115610f9a57610f996128de565b5b0361100b575f808981526020019081526020015f205f0160189054906101000a900463ffffffff1663ffffffff1642101561100a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100190613601565b60405180910390fd5b5b6001600481111561101f5761101e6128de565b5b5f808a81526020019081526020015f205f01601c9054906101000a900460ff166004811115611051576110506128de565b5b036110c2575f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156110c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b89061368f565b60405180910390fd5b5b60045f808a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156110f8576110f76128de565b5b02179055507fbdd7a4be6d82798a500b59077706b12d3f45acf5504828919f92501307b2b9538860405161112c9190612f8b565b60405180910390a15f868861114191906134d0565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036111bf573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156111b9573d5f803e3d5ffd5b506111f0565b5f8390506111ee33838373ffffffffffffffffffffffffffffffffffffffff166121e89092919063ffffffff16565b505b505050505050505050565b5f600481111561120e5761120d6128de565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660048111156112405761123f6128de565b5b14611280576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112779061371d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036112ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112e5906137ab565b60405180910390fd5b5f3411611330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132790613839565b60405180910390fd5b853411611372576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611369906138c7565b60405180910390fd5b5f6003873461138191906138e5565b88883389895f60405160200161139d9796959493929190612e2c565b6040516020818303038152906040526040516113b99190612efe565b602060405180830381855afa1580156113d4573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff1681526020016001600481111561142c5761142b6128de565b5b8152505f808a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff021916908360048111156114e6576114e56128de565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358860405161151d9190612f8b565b60405180910390a15050505050505050565b5f6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156290613962565b60405180910390fd5b6002600481111561157f5761157e6128de565b5b5f808981526020019081526020015f205f01601c9054906101000a900460ff1660048111156115b1576115b06128de565b5b146115f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115e8906139f0565b60405180910390fd5b5f6003878733888860028960405160200161160c9190613423565b6040516020818303038152906040526040516116289190612efe565b602060405180830381855afa158015611643573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906116669190613451565b8860405160200161167d9796959493929190612e2c565b6040516020818303038152906040526040516116999190612efe565b602060405180830381855afa1580156116b4573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461173e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161173590612f5e565b60405180910390fd5b60035f808a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115611774576117736128de565b5b02179055507f0d0da0df275f85bed3a5fe7ae79f3559341a3f9ccd8e010133438135bda00a8788846040516117aa92919061347c565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611892573373ffffffffffffffffffffffffffffffffffffffff166108fc8890811502906040515f60405180830381858888f19350505050158015611828573d5f803e3d5ffd5b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f1935050505015801561188c573d5f803e3d5ffd5b5061190e565b5f8290506118c133898373ffffffffffffffffffffffffffffffffffffffff166121e89092919063ffffffff16565b61190c7f0000000000000000000000000000000000000000000000000000000000000000888373ffffffffffffffffffffffffffffffffffffffff166121e89092919063ffffffff16565b505b5050505050505050565b5f600481111561192b5761192a6128de565b5b5f808b81526020019081526020015f205f01601c9054906101000a900460ff16600481111561195d5761195c6128de565b5b1461199d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161199490613a7e565b60405180910390fd5b5f88116119df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d690613ae6565b60405180910390fd5b5f8711611a21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a1890613b4e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611a8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a86906137ab565b60405180910390fd5b5f60038989883389898d604051602001611aaf9796959493929190612e2c565b604051602081830303815290604052604051611acb9190612efe565b602060405180830381855afa158015611ae6573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115611b3e57611b3d6128de565b5b8152505f808c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115611bf857611bf76128de565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358a604051611c2f9190612f8b565b60405180910390a15f879050611c7333308b8d611c4c91906134d0565b8473ffffffffffffffffffffffffffffffffffffffff16612267909392919063ffffffff16565b5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f808383810190611cb591906130cd565b90505f6004811115611cca57611cc96128de565b5b5f80835f015181526020019081526020015f205f01601c9054906101000a900460ff166004811115611cff57611cfe6128de565b5b14611d3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3690613bdc565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603611db1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611da8906131d0565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603611e23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1a90613238565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e8c906132c6565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614611f03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611efa9061332e565b60405180910390fd5b5f8511611f45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3c90613c44565b60405180910390fd5b611f5281602001516121d7565b15611f92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f8990613396565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c604051602001611fc29796959493929190613c62565b604051602081830303815290604052604051611fde9190612efe565b602060405180830381855afa158015611ff9573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020018360a0015163ffffffff16815260200160016004811115612059576120586128de565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115612116576121156128de565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd935825f01516040516121509190612f8b565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b612262838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb858560405160240161221b929190613cf1565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506122e9565b505050565b6122e3848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161229c93929190613d18565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506122e9565b50505050565b5f612313828473ffffffffffffffffffffffffffffffffffffffff1661237e90919063ffffffff16565b90505f8151141580156123375750808060200190518101906123359190613d77565b155b1561237957826040517f5274afe70000000000000000000000000000000000000000000000000000000081526004016123709190612c5a565b60405180910390fd5b505050565b606061238b83835f612393565b905092915050565b6060814710156123da57306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016123d19190612c5a565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516124029190612efe565b5f6040518083038185875af1925050503d805f811461243c576040519150601f19603f3d011682016040523d82523d5f602084013e612441565b606091505b509150915061245186838361245c565b925050509392505050565b6060826124715761246c826124e9565b6124e1565b5f825114801561249757505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156124d957836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016124d09190612c5a565b60405180910390fd5b8190506124e2565b5b9392505050565b5f815111156124fb5780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6125728161253e565b811461257c575f80fd5b50565b5f8135905061258d81612569565b92915050565b5f602082840312156125a8576125a7612536565b5b5f6125b58482850161257f565b91505092915050565b5f8115159050919050565b6125d2816125be565b82525050565b5f6020820190506125eb5f8301846125c9565b92915050565b5f819050919050565b612603816125f1565b811461260d575f80fd5b50565b5f8135905061261e816125fa565b92915050565b5f819050919050565b61263681612624565b8114612640575f80fd5b50565b5f813590506126518161262d565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61268082612657565b9050919050565b61269081612676565b811461269a575f80fd5b50565b5f813590506126ab81612687565b92915050565b5f805f805f805f60e0888a0312156126cc576126cb612536565b5b5f6126d98a828b01612610565b97505060206126ea8a828b01612643565b96505060406126fb8a828b01612643565b955050606061270c8a828b0161269d565b945050608061271d8a828b01612610565b93505060a061272e8a828b01612610565b92505060c061273f8a828b0161269d565b91505092959891949750929550565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261276f5761276e61274e565b5b8235905067ffffffffffffffff81111561278c5761278b612752565b5b6020830191508360018202830111156127a8576127a7612756565b5b9250929050565b5f805f805f608086880312156127c8576127c7612536565b5b5f6127d58882890161269d565b95505060206127e68882890161269d565b94505060406127f788828901612643565b935050606086013567ffffffffffffffff8111156128185761281761253a565b5b6128248882890161275a565b92509250509295509295909350565b61283c8161253e565b82525050565b5f6020820190506128555f830184612833565b92915050565b5f602082840312156128705761286f612536565b5b5f61287d84828501612610565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b6128ba81612886565b82525050565b5f63ffffffff82169050919050565b6128d8816128c0565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6005811061291c5761291b6128de565b5b50565b5f81905061292c8261290b565b919050565b5f61293b8261291f565b9050919050565b61294b81612931565b82525050565b5f6080820190506129645f8301876128b1565b61297160208301866128cf565b61297e60408301856128cf565b61298b6060830184612942565b95945050505050565b61299d816128c0565b81146129a7575f80fd5b50565b5f813590506129b881612994565b92915050565b5f805f805f805f60e0888a0312156129d9576129d8612536565b5b5f6129e68a828b01612610565b97505060206129f78a828b01612643565b9650506040612a088a828b0161269d565b9550506060612a198a828b01612610565b9450506080612a2a8a828b01612610565b93505060a0612a3b8a828b016129aa565b92505060c0612a4c8a828b016129aa565b91505092959891949750929550565b5f8083601f840112612a7057612a6f61274e565b5b8235905067ffffffffffffffff811115612a8d57612a8c612752565b5b602083019150836020820283011115612aa957612aa8612756565b5b9250929050565b5f805f805f805f8060a0898b031215612acc57612acb612536565b5b5f612ad98b828c0161269d565b9850506020612aea8b828c0161269d565b975050604089013567ffffffffffffffff811115612b0b57612b0a61253a565b5b612b178b828c01612a5b565b9650965050606089013567ffffffffffffffff811115612b3a57612b3961253a565b5b612b468b828c01612a5b565b9450945050608089013567ffffffffffffffff811115612b6957612b6861253a565b5b612b758b828c0161275a565b92509250509295985092959890939650565b5f805f805f805f805f6101208a8c031215612ba557612ba4612536565b5b5f612bb28c828d01612610565b9950506020612bc38c828d01612643565b9850506040612bd48c828d01612643565b9750506060612be58c828d0161269d565b9650506080612bf68c828d0161269d565b95505060a0612c078c828d01612610565b94505060c0612c188c828d01612610565b93505060e0612c298c828d016129aa565b925050610100612c3b8c828d016129aa565b9150509295985092959850929598565b612c5481612676565b82525050565b5f602082019050612c6d5f830184612c4b565b92915050565b5f805f805f8060a08789031215612c8d57612c8c612536565b5b5f612c9a89828a0161269d565b9650506020612cab89828a0161269d565b9550506040612cbc89828a01612643565b9450506060612ccd89828a01612643565b935050608087013567ffffffffffffffff811115612cee57612ced61253a565b5b612cfa89828a0161275a565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f612d73602a83612d09565b9150612d7e82612d19565b604082019050919050565b5f6020820190508181035f830152612da081612d67565b9050919050565b5f819050919050565b612dc1612dbc82612624565b612da7565b82525050565b5f8160601b9050919050565b5f612ddd82612dc7565b9050919050565b5f612dee82612dd3565b9050919050565b612e06612e0182612676565b612de4565b82525050565b5f819050919050565b612e26612e21826125f1565b612e0c565b82525050565b5f612e37828a612db0565b602082019150612e478289612db0565b602082019150612e578288612df5565b601482019150612e678287612df5565b601482019150612e778286612e15565b602082019150612e878285612e15565b602082019150612e978284612df5565b60148201915081905098975050505050505050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f612ed882612eac565b612ee28185612eb6565b9350612ef2818560208601612ec0565b80840191505092915050565b5f612f098284612ece565b915081905092915050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f612f48601383612d09565b9150612f5382612f14565b602082019050919050565b5f6020820190508181035f830152612f7581612f3c565b9050919050565b612f85816125f1565b82525050565b5f602082019050612f9e5f830184612f7c565b92915050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612fee82612fa8565b810181811067ffffffffffffffff8211171561300d5761300c612fb8565b5b80604052505050565b5f61301f61252d565b905061302b8282612fe5565b919050565b5f60c0828403121561304557613044612fa4565b5b61304f60c0613016565b90505f61305e84828501612610565b5f8301525060206130718482850161269d565b60208301525060406130858482850161269d565b604083015250606061309984828501612610565b60608301525060806130ad84828501612610565b60808301525060a06130c1848285016129aa565b60a08301525092915050565b5f60c082840312156130e2576130e1612536565b5b5f6130ef84828501613030565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f613152602a83612d09565b915061315d826130f8565b604082019050919050565b5f6020820190508181035f83015261317f81613146565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f6131ba601e83612d09565b91506131c582613186565b602082019050919050565b5f6020820190508181035f8301526131e7816131ae565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f613222601e83612d09565b915061322d826131ee565b602082019050919050565b5f6020820190508181035f83015261324f81613216565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f6132b0602383612d09565b91506132bb82613256565b604082019050919050565b5f6020820190508181035f8301526132dd816132a4565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f613318601b83612d09565b9150613323826132e4565b602082019050919050565b5f6020820190508181035f8301526133458161330c565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f613380601a83612d09565b915061338b8261334c565b602082019050919050565b5f6020820190508181035f8301526133ad81613374565b9050919050565b5f6133bf8289612df5565b6014820191506133cf8288612df5565b6014820191506133df8287612e15565b6020820191506133ef8286612e15565b6020820191506133ff8285612df5565b60148201915061340f8284612db0565b602082019150819050979650505050505050565b5f61342e8284612e15565b60208201915081905092915050565b5f8151905061344b816125fa565b92915050565b5f6020828403121561346657613465612536565b5b5f6134738482850161343d565b91505092915050565b5f60408201905061348f5f830185612f7c565b61349c6020830184612f7c565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6134da82612624565b91506134e583612624565b92508282019050808211156134fd576134fc6134a3565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e74206f722054616b6572417070726f7665640000000000602082015250565b5f61355d603b83612d09565b915061356882613503565b604082019050919050565b5f6020820190508181035f83015261358a81613551565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f6135eb603883612d09565b91506135f682613591565b604082019050919050565b5f6020820190508181035f830152613618816135df565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e74207072652d617070726f7665206c6f636b2074696d65000000602082015250565b5f613679603d83612d09565b91506136848261361f565b604082019050919050565b5f6020820190508181035f8301526136a68161366d565b9050919050565b7f54616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f613707602483612d09565b9150613712826136ad565b604082019050919050565b5f6020820190508181035f830152613734816136fb565b9050919050565b7f5265636569766572206d757374206e6f74206265207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f613795602183612d09565b91506137a08261373b565b604082019050919050565b5f6020820190508181035f8301526137c281613789565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f613823602383612d09565b915061382e826137c9565b604082019050919050565b5f6020820190508181035f83015261385081613817565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e20645f8201527f6578206665650000000000000000000000000000000000000000000000000000602082015250565b5f6138b1602683612d09565b91506138bc82613857565b604082019050919050565b5f6020820190508181035f8301526138de816138a5565b9050919050565b5f6138ef82612624565b91506138fa83612624565b9250828203905081811115613912576139116134a3565b5b92915050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f61394c601d83612d09565b915061395782613918565b602082019050919050565b5f6020820190508181035f83015261397981613940565b9050919050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520545f8201527f616b6572417070726f7665640000000000000000000000000000000000000000602082015250565b5f6139da602c83612d09565b91506139e582613980565b604082019050919050565b5f6020820190508181035f830152613a07816139ce565b9050919050565b7f4552433230207632207061796d656e7420697320616c726561647920696e69745f8201527f69616c697a656400000000000000000000000000000000000000000000000000602082015250565b5f613a68602783612d09565b9150613a7382613a0e565b604082019050919050565b5f6020820190508181035f830152613a9581613a5c565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f613ad0601783612d09565b9150613adb82613a9c565b602082019050919050565b5f6020820190508181035f830152613afd81613ac4565b9050919050565b7f44657820666565206d757374206e6f74206265207a65726f00000000000000005f82015250565b5f613b38601883612d09565b9150613b4382613b04565b602082019050919050565b5f6020820190508181035f830152613b6581613b2c565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f613bc6602b83612d09565b9150613bd182613b6c565b604082019050919050565b5f6020820190508181035f830152613bf381613bba565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f613c2e601c83612d09565b9150613c3982613bfa565b602082019050919050565b5f6020820190508181035f830152613c5b81613c22565b9050919050565b5f613c6d828a612df5565b601482019150613c7d8289612df5565b601482019150613c8d8288612e15565b602082019150613c9d8287612e15565b602082019150613cad8286612df5565b601482019150613cbd8285612db0565b602082019150613ccd8284612db0565b60208201915081905098975050505050505050565b613ceb81612624565b82525050565b5f604082019050613d045f830185612c4b565b613d116020830184613ce2565b9392505050565b5f606082019050613d2b5f830186612c4b565b613d386020830185612c4b565b613d456040830184613ce2565b949350505050565b613d56816125be565b8114613d60575f80fd5b50565b5f81519050613d7181613d4d565b92915050565b5f60208284031215613d8c57613d8b612536565b5b5f613d9984828501613d63565b9150509291505056fea26469706673582212204d2f7890889da1a093cdba99ca77234cfd0022951ad95669c493b1ac88166efe64736f6c634300081a0033 \ No newline at end of file From fdb7fefcff7ce8548ea5299a297f6803768d653d Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Jul 2024 15:50:35 +0700 Subject: [PATCH 122/233] more logs --- mm2src/coins/eth/eth_swap_v2.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index d4b0955689..b8cb680d92 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -307,7 +307,9 @@ impl EthCoin { token_address: Address, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("erc20TakerPayment")?; + log!("function: {:?}", function); let id = self.etomic_swap_id(args.payment_time_lock, &args.maker_secret_hash); + log!("payment_amount: {:?}", args.payment_amount.clone()); let data = function.encode_input(&[ Token::FixedBytes(id), Token::Uint(args.payment_amount), From 52d4ddfda2ddf79bca1f8c19f49a6d5b957af2d0 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Jul 2024 16:23:52 +0700 Subject: [PATCH 123/233] init erc20 --- .../tests/docker_tests/eth_docker_tests.rs | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 7b43219162..8d49678b3f 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1509,7 +1509,12 @@ impl SwapAddresses { } } -fn eth_coin_v2_activation_with_random_privkey(ticker: &str, conf: &Json, swap_addr: SwapAddresses) -> EthCoin { +fn eth_coin_v2_activation_with_random_privkey( + ticker: &str, + conf: &Json, + swap_addr: SwapAddresses, + erc20: bool, +) -> EthCoin { let build_policy = EthPrivKeyBuildPolicy::IguanaPrivKey(random_secp256k1_secret()); let node = EthNode { url: GETH_RPC_URL.to_string(), @@ -1540,14 +1545,22 @@ fn eth_coin_v2_activation_with_random_privkey(ticker: &str, conf: &Json, swap_ad let my_address = block_on(coin.my_addr()); fill_eth(my_address, U256::from(10).pow(U256::from(20))); fill_erc20(my_address, U256::from(10000000000u64)); + if erc20 { + let coin_type = EthCoinType::Erc20 { + platform: ETH.to_string(), + token_addr: erc20_contract(), + }; + let coin = block_on(coin.set_coin_type(coin_type)); + return coin; + } coin } #[test] fn send_and_refund_taker_funding_by_secret_eth() { thread::sleep(Duration::from_secs(1)); - let taker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init()); - let maker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init()); + let taker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init(), false); + let maker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init(), false); let taker_secret = vec![0; 32]; let taker_secret_hash = sha256(&taker_secret).to_vec(); @@ -1614,8 +1627,8 @@ fn send_and_refund_taker_funding_by_secret_eth() { fn send_and_refund_taker_funding_by_secret_erc20() { thread::sleep(Duration::from_secs(3)); let erc20_conf = &erc20_dev_conf(&erc20_contract_checksum()); - let taker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init()); - let maker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init()); + let taker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init(), true); + let maker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init(), true); let taker_secret = vec![0; 32]; let taker_secret_hash = sha256(&taker_secret).to_vec(); @@ -1684,11 +1697,10 @@ fn send_and_refund_taker_funding_by_secret_erc20() { assert_eq!(balance_before_payment, balance_after_refund); } -#[ignore] #[test] fn send_and_refund_taker_funding_timelock_eth() { - let taker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init()); - let maker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init()); + let taker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init(), false); + let maker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init(), false); let taker_secret = vec![0; 32]; let taker_secret_hash = sha256(&taker_secret).to_vec(); @@ -1756,13 +1768,12 @@ fn send_and_refund_taker_funding_timelock_eth() { assert_eq!(balance_before_payment, balance_after_refund); } -#[ignore] #[test] fn send_and_refund_taker_funding_timelock_erc20() { thread::sleep(Duration::from_secs(2)); let erc20_conf = &erc20_dev_conf(&erc20_contract_checksum()); - let taker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init()); - let maker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init()); + let taker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init(), true); + let maker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init(), true); let taker_secret = vec![0; 32]; let taker_secret_hash = sha256(&taker_secret).to_vec(); From 0d34688315866d58bed6eb24a5b722d5d9205738 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Jul 2024 16:53:40 +0700 Subject: [PATCH 124/233] provide 0 to send value in refund methods --- mm2src/coins/eth/eth_swap_v2.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index b8cb680d92..db8f889f94 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -116,7 +116,7 @@ impl EthCoin { )) })?; self.sign_and_send_transaction( - U256::from(0), + 0.into(), Action::Call(taker_swap_v2_contract), data, U256::from(self.gas_limit.erc20_payment), @@ -125,7 +125,7 @@ impl EthCoin { .await } else { self.sign_and_send_transaction( - U256::from(0), + 0.into(), Action::Call(taker_swap_v2_contract), data, U256::from(self.gas_limit.erc20_payment), @@ -203,7 +203,7 @@ impl EthCoin { let data = try_tx_s!(self.prepare_taker_refund_payment_timelock_data(args).await); self.sign_and_send_transaction( - payment_amount, + 0.into(), Action::Call(taker_swap_v2_contract), data, U256::from(gas_limit), @@ -257,7 +257,7 @@ impl EthCoin { let data = try_tx_s!(self.prepare_taker_refund_payment_secret_data(&refund_args).await); self.sign_and_send_transaction( - payment_amount, + 0.into(), Action::Call(taker_swap_v2_contract), data, U256::from(gas_limit), @@ -307,9 +307,7 @@ impl EthCoin { token_address: Address, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("erc20TakerPayment")?; - log!("function: {:?}", function); let id = self.etomic_swap_id(args.payment_time_lock, &args.maker_secret_hash); - log!("payment_amount: {:?}", args.payment_amount.clone()); let data = function.encode_input(&[ Token::FixedBytes(id), Token::Uint(args.payment_amount), From 7cd09cae51242024e9b8496cd8a1ce69ac259d21 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Jul 2024 17:50:48 +0700 Subject: [PATCH 125/233] eth tpu v2: update ValidateTakerFundingArgs fields --- mm2src/coins/eth/eth_swap_v2.rs | 8 ++--- mm2src/coins/lp_coins.rs | 11 +++++-- mm2src/coins/utxo/utxo_common.rs | 4 +-- mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs | 6 ++-- .../tests/docker_tests/eth_docker_tests.rs | 2 ++ .../tests/docker_tests/swap_proto_v2_tests.rs | 30 ++++++++++++------- 6 files changed, 40 insertions(+), 21 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index db8f889f94..d021cc87b9 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -56,10 +56,6 @@ impl EthCoin { &(args.trading_amount.clone() + args.premium_amount.clone()), self.decimals )); - let eth_total_payment = try_tx_s!(wei_from_big_decimal( - &(args.dex_fee.fee_amount().to_decimal() + args.trading_amount + args.premium_amount), - self.decimals - )); // TODO add maker_pub created by legacy derive_htlc_pubkey support additionally? // as derive_htlc_pubkey_v2 function is used for swap_v2, we can call public_to_address let maker_address = public_to_address(&Public::from_slice(args.maker_pub)); @@ -79,6 +75,10 @@ impl EthCoin { match &self.coin_type { EthCoinType::Eth => { let data = try_tx_s!(self.prepare_taker_eth_funding_data(&funding_args).await); + let eth_total_payment = try_tx_s!(wei_from_big_decimal( + &(args.dex_fee.fee_amount().to_decimal() + args.trading_amount + args.premium_amount), + self.decimals + )); self.sign_and_send_transaction( eth_total_payment, Action::Call(taker_swap_v2_contract), diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index a33596fe4d..fe115e7860 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1361,12 +1361,17 @@ pub struct GenTakerFundingSpendArgs<'a, Coin: ParseCoinAssocTypes + ?Sized> { pub struct ValidateTakerFundingArgs<'a, Coin: ParseCoinAssocTypes + ?Sized> { /// Taker funding transaction pub funding_tx: &'a Coin::Tx, - /// Taker will be able to refund the payment after this timestamp - pub time_lock: u64, + /// The timestamp after which the taker can refund the funding transaction if the maker hasn't pre-approved the transaction + /// In UTXO case: Taker will be able to refund the payment after this timestamp + pub funding_time_lock: u64, + /// The timestamp after which the taker can refund the payment transaction if the maker hasn't claimed it by revealing their secret + pub payment_time_lock: u64, /// The hash of the secret generated by taker pub taker_secret_hash: &'a [u8], + /// The hash of the secret generated by maker + pub maker_secret_hash: &'a [u8], /// Taker's pubkey - pub other_pub: &'a Coin::Pubkey, + pub taker_pub: &'a Coin::Pubkey, /// DEX fee amount pub dex_fee: &'a DexFee, /// Additional reward for maker (premium) diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 12c18f602c..2c1e412c04 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -4886,14 +4886,14 @@ where let expected_amount_sat = sat_from_big_decimal(&total_expected_amount, coin.as_ref().decimals)?; let time_lock = args - .time_lock + .funding_time_lock .try_into() .map_to_mm(|e: TryFromIntError| ValidateSwapV2TxError::LocktimeOverflow(e.to_string()))?; let redeem_script = swap_proto_v2_scripts::taker_funding_script( time_lock, args.taker_secret_hash, - args.other_pub, + args.taker_pub, maker_htlc_key_pair.public(), ); let expected_output = TransactionOutput { diff --git a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs index 6e9555c10f..25e0310af7 100644 --- a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs @@ -1157,9 +1157,11 @@ impl Date: Tue, 23 Jul 2024 18:26:43 +0700 Subject: [PATCH 126/233] leave only send_and_refund_taker_funding_by_secret_erc20 test --- mm2src/coins/eth/eth_swap_v2.rs | 1 - mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index d021cc87b9..ca3ef8ad25 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -99,7 +99,6 @@ impl EthCoin { .map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?; let data = try_tx_s!(self.prepare_taker_erc20_funding_data(&funding_args, *token_addr).await); if allowed < payment_amount { - log!("Allowed: {}, payment_amount: {}", allowed, payment_amount); let approved_tx = self.approve(taker_swap_v2_contract, U256::max_value()).compat().await?; self.wait_for_required_allowance( taker_swap_v2_contract, diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index d90bd43a18..194a2536d3 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1556,6 +1556,7 @@ fn eth_coin_v2_activation_with_random_privkey( coin } +#[ignore] #[test] fn send_and_refund_taker_funding_by_secret_eth() { thread::sleep(Duration::from_secs(1)); @@ -1625,7 +1626,6 @@ fn send_and_refund_taker_funding_by_secret_eth() { #[test] fn send_and_refund_taker_funding_by_secret_erc20() { - thread::sleep(Duration::from_secs(3)); let erc20_conf = &erc20_dev_conf(&erc20_contract_checksum()); let taker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init(), true); let maker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init(), true); @@ -1662,7 +1662,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { }; let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); - log!("Taker sent ERC20 funding, tx hash {:02x}", funding_tx.tx_hash()); + log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); wait_for_confirmations(&taker_coin, &funding_tx, 100); From 2ffe13411ef1d55a4f79f148ddc472184944a3dc Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 23 Jul 2024 20:14:01 +0700 Subject: [PATCH 127/233] sepolia: fix swap id, test refund by secret and timelock --- mm2src/coins/eth/eth_swap_v2.rs | 3 +- .../tests/docker_tests/docker_tests_common.rs | 13 +- .../tests/docker_tests/eth_docker_tests.rs | 142 ++++++++++++++---- 3 files changed, 128 insertions(+), 30 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index ca3ef8ad25..c9b8f871d2 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,7 +1,6 @@ use super::eth::{wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; use super::{RefundFundingSecretArgs, RefundTakerPaymentArgs, SendTakerFundingArgs, SwapTxTypeWithSecretHash, Transaction, TransactionErr, ValidateSwapV2TxResult, ValidateTakerFundingArgs}; -use bitcrypto::sha256; use enum_derives::EnumFromStringify; use ethabi::Token; use ethcore_transaction::Action; @@ -361,7 +360,7 @@ impl EthCoin { args: &TakerRefundSecretArgs, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("refundTakerPaymentSecret")?; - let id = self.etomic_swap_id(args.payment_time_lock, sha256(&args.taker_secret).as_slice()); + let id = self.etomic_swap_id(args.payment_time_lock, &args.maker_secret_hash); let data = function.encode_input(&[ Token::FixedBytes(id), Token::Uint(args.payment_amount), diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 09e6b1d5ef..d1b3ae508d 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -58,7 +58,7 @@ lazy_static! { // Due to the SLP protocol limitations only 19 outputs (18 + change) can be sent in one transaction, which is sufficient for now though. // Supply more privkeys when 18 will be not enough. pub static ref SLP_TOKEN_OWNERS: Mutex> = Mutex::new(Vec::with_capacity(18)); - pub static ref MM_CTX: MmArc = MmCtxBuilder::new().into_mm_arc(); + pub static ref MM_CTX: MmArc = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); /// We need a second `MmCtx` instance when we use the same private keys for Maker and Taker across various tests. /// When enabling coins for both Maker and Taker, two distinct coin instances are created. /// This means that different instances of the same coin should have separate global nonce locks. @@ -80,12 +80,18 @@ pub static mut QTUM_CONF_PATH: Option = None; pub static mut GETH_ACCOUNT: H160Eth = H160Eth::zero(); /// ERC20 token address on Geth dev node pub static mut GETH_ERC20_CONTRACT: H160Eth = H160Eth::zero(); +#[allow(dead_code)] +pub static mut SEPOLIA_ERC20_CONTRACT: H160Eth = H160Eth::zero(); /// Swap contract address on Geth dev node pub static mut GETH_SWAP_CONTRACT: H160Eth = H160Eth::zero(); /// Maker Swap V2 contract address on Geth dev node pub static mut GETH_MAKER_SWAP_V2: H160Eth = H160Eth::zero(); /// Taker Swap V2 contract address on Geth dev node pub static mut GETH_TAKER_SWAP_V2: H160Eth = H160Eth::zero(); +#[allow(dead_code)] +pub static mut SEPOLIA_TAKER_SWAP_V2: H160Eth = H160Eth::zero(); +#[allow(dead_code)] +pub static mut SEPOLIA_MAKER_SWAP_V2: H160Eth = H160Eth::zero(); /// Swap contract (with watchers support) address on Geth dev node pub static mut GETH_WATCHERS_SWAP_CONTRACT: H160Eth = H160Eth::zero(); /// ERC721 token address on Geth dev node @@ -1665,6 +1671,11 @@ pub fn init_geth_node() { SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2 = EthAddress::from_str("0x9eb88cd58605d8fb9b14652d6152727f7e95fb4d").unwrap(); SEPOLIA_ERC721_CONTRACT = EthAddress::from_str("0xbac1c9f2087f39caaa4e93412c6412809186870e").unwrap(); SEPOLIA_ERC1155_CONTRACT = EthAddress::from_str("0xfb53b8764be6033d89ceacafa36631b09d60a1d2").unwrap(); + // TODO update this + SEPOLIA_ERC20_CONTRACT = EthAddress::from_str("0x7Cc9F2c1c3B797D09B9d1CCd7FDcD2539a4b3874").unwrap(); + SEPOLIA_TAKER_SWAP_V2 = EthAddress::from_str("0x7Cc9F2c1c3B797D09B9d1CCd7FDcD2539a4b3874").unwrap(); + // TODO update this + SEPOLIA_MAKER_SWAP_V2 = EthAddress::from_str("0x7Cc9F2c1c3B797D09B9d1CCd7FDcD2539a4b3874").unwrap(); let alice_passphrase = get_passphrase!(".env.client", "ALICE_PASSPHRASE").unwrap(); let alice_keypair = key_pair_from_seed(&alice_passphrase).unwrap(); diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 194a2536d3..872bf1cfe1 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -2,8 +2,9 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC7 GETH_ERC1155_CONTRACT, GETH_ERC20_CONTRACT, GETH_ERC721_CONTRACT, GETH_MAKER_SWAP_V2, GETH_NFT_MAKER_SWAP_V2, GETH_NFT_SWAP_CONTRACT, GETH_NONCE_LOCK, GETH_RPC_URL, GETH_SWAP_CONTRACT, GETH_TAKER_SWAP_V2, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, - MM_CTX, MM_CTX1, SEPOLIA_ERC1155_CONTRACT, SEPOLIA_ERC721_CONTRACT, - SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2, SEPOLIA_NONCE_LOCK, SEPOLIA_RPC_URL, SEPOLIA_WEB3}; + MM_CTX, MM_CTX1, SEPOLIA_ERC1155_CONTRACT, SEPOLIA_ERC20_CONTRACT, + SEPOLIA_ERC721_CONTRACT, SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2, SEPOLIA_MAKER_SWAP_V2, + SEPOLIA_NONCE_LOCK, SEPOLIA_RPC_URL, SEPOLIA_TAKER_SWAP_V2, SEPOLIA_WEB3}; use crate::common::Future01CompatExt; use bitcrypto::{dhash160, sha256}; use coins::eth::gas_limit::ETH_MAX_TRADE_GAS; @@ -25,8 +26,9 @@ use ethereum_types::U256; use futures01::Future; use mm2_core::mm_ctx::MmArc; use mm2_number::{BigDecimal, BigUint}; -use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, nft_dev_conf, nft_sepolia_conf}; +use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, eth_sepolia_conf, nft_dev_conf, nft_sepolia_conf}; use serde_json::Value as Json; +use std::str::FromStr; use std::thread; use std::time::Duration; use web3::contract::{Contract, Options}; @@ -60,6 +62,10 @@ pub fn maker_swap_v2() -> Address { unsafe { GETH_MAKER_SWAP_V2 } } /// /// GETH_TAKER_SWAP_V2 is set once during initialization before tests start pub fn taker_swap_v2() -> Address { unsafe { GETH_TAKER_SWAP_V2 } } +#[allow(dead_code)] +pub fn sepolia_taker_swap_v2() -> Address { unsafe { SEPOLIA_TAKER_SWAP_V2 } } +#[allow(dead_code)] +pub fn sepolia_maker_swap_v2() -> Address { unsafe { SEPOLIA_MAKER_SWAP_V2 } } #[allow(dead_code)] /// # Safety @@ -81,9 +87,13 @@ pub fn watchers_swap_contract() -> Address { unsafe { GETH_WATCHERS_SWAP_CONTRAC /// /// GETH_ERC20_CONTRACT is set once during initialization before tests start pub fn erc20_contract() -> Address { unsafe { GETH_ERC20_CONTRACT } } +#[allow(dead_code)] +pub fn sepolia_erc20_contract() -> Address { unsafe { SEPOLIA_ERC20_CONTRACT } } /// Return ERC20 dev token contract address in checksum format pub fn erc20_contract_checksum() -> String { checksum_address(&format!("{:02x}", erc20_contract())) } +#[allow(dead_code)] +pub fn sepolia_erc20_contract_checksum() -> String { checksum_address(&format!("{:02x}", sepolia_erc20_contract())) } #[allow(dead_code)] /// # Safety @@ -169,12 +179,25 @@ fn check_eth_balance(address: Address) -> U256 { block_on(GETH_WEB3.eth().balance(address, None)).unwrap() } +#[allow(dead_code)] +fn sepolia_check_eth_balance(address: Address) -> U256 { + let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); + block_on(SEPOLIA_WEB3.eth().balance(address, None)).unwrap() +} + fn check_erc20_balance(address: Address) -> U256 { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc20_contract = Contract::from_json(GETH_WEB3.eth(), erc20_contract(), ERC20_ABI.as_bytes()).unwrap(); block_on(erc20_contract.query("balanceOf", (address,), None, Options::default(), None)).unwrap() } +#[allow(dead_code)] +fn sepolia_check_erc20_balance(address: Address) -> U256 { + let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); + let erc20_contract = Contract::from_json(SEPOLIA_WEB3.eth(), erc20_contract(), ERC20_ABI.as_bytes()).unwrap(); + block_on(erc20_contract.query("balanceOf", (address,), None, Options::default(), None)).unwrap() +} + fn mint_erc721(to_addr: Address, token_id: U256) { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc721_contract = @@ -492,6 +515,70 @@ fn global_nft_from_privkey( global_nft } +#[allow(dead_code)] +/// Can be used to generate coin from Sepolia Maker/Taker priv keys. +fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, conf: &Json) -> EthCoin { + let swap_addr = SwapAddresses { + swap_v2_contracts: SwapV2Contracts { + maker_swap_v2_contract: sepolia_maker_swap_v2(), + taker_swap_v2_contract: sepolia_taker_swap_v2(), + nft_maker_swap_v2_contract: sepolia_etomic_maker_nft(), + }, + swap_contract_address: sepolia_taker_swap_v2(), + fallback_swap_contract_address: sepolia_taker_swap_v2(), + }; + + let priv_key = Secp256k1Secret::from(secret); + let build_policy = EthPrivKeyBuildPolicy::IguanaPrivKey(priv_key); + + let node = EthNode { + url: SEPOLIA_RPC_URL.to_string(), + gui_auth: false, + }; + let platform_request = EthActivationV2Request { + nodes: vec![node], + rpc_mode: Default::default(), + swap_contract_address: swap_addr.swap_contract_address, + swap_v2_contracts: Some(swap_addr.swap_v2_contracts), + fallback_swap_contract: Some(swap_addr.fallback_swap_contract_address), + contract_supports_watchers: false, + mm2: None, + required_confirmations: None, + priv_key_policy: Default::default(), + enable_params: Default::default(), + path_to_address: Default::default(), + gap_limit: None, + }; + + let coin = block_on(eth_coin_from_conf_and_request_v2( + ctx, + ticker, + conf, + platform_request, + build_policy, + )) + .unwrap(); + + let coins_ctx = CoinsContext::from_ctx(ctx).unwrap(); + let mut coins = block_on(coins_ctx.lock_coins()); + coins.insert( + coin.ticker().into(), + MmCoinStruct::new(MmCoinEnum::EthCoin(coin.clone())), + ); + coin +} + +#[allow(dead_code)] +fn get_or_create_sepolia_coin(ctx: &MmArc, priv_key: &'static str, ticker: &str, conf: &Json) -> EthCoin { + match block_on(lp_coinfind(ctx, ticker)).unwrap() { + None => sepolia_coin_from_privkey(ctx, priv_key, ticker, conf), + Some(mm_coin) => match mm_coin { + MmCoinEnum::EthCoin(coin) => coin, + _ => panic!("Unexpected coin type found. Expected MmCoinEnum::EthCoin"), + }, + } +} + #[allow(dead_code)] fn send_safe_transfer_from( global_nft: &EthCoin, @@ -1556,12 +1643,11 @@ fn eth_coin_v2_activation_with_random_privkey( coin } -#[ignore] #[test] fn send_and_refund_taker_funding_by_secret_eth() { thread::sleep(Duration::from_secs(1)); - let taker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init(), false); - let maker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init(), false); + let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf()); + let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf()); let taker_secret = vec![0; 32]; let taker_secret_hash = sha256(&taker_secret).to_vec(); @@ -1571,11 +1657,14 @@ fn send_and_refund_taker_funding_by_secret_eth() { let payment_time_lock = now_sec() + 1000; let taker_address = block_on(taker_coin.my_addr()); + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); - let balance_before_payment = check_eth_balance(taker_address); + let balance_before_payment = sepolia_check_eth_balance(taker_address); log!("Taker ETH balance before payment: {}", balance_before_payment); - let dex_fee = &DexFee::Standard("0.1".into()); + let dex_fee = &DexFee::Standard("0.00001".into()); + let trading_amount = BigDecimal::from_str("0.0001").unwrap(); + let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); let payment_args = SendTakerFundingArgs { funding_time_lock, @@ -1585,7 +1674,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { maker_pub: maker_pub.as_bytes(), dex_fee, premium_amount: BigDecimal::default(), - trading_amount: 1.into(), + trading_amount: trading_amount.clone(), swap_unique_data: &[], wait_for_confirmation_until: 0, }; @@ -1594,7 +1683,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { wait_for_confirmations(&taker_coin, &funding_tx, 100); - let balance_after_payment = check_eth_balance(taker_address); + let balance_after_payment = sepolia_check_eth_balance(taker_address); log!("Taker ETH balance after payment: {}", balance_after_payment); let refund_args = RefundFundingSecretArgs { @@ -1607,10 +1696,11 @@ fn send_and_refund_taker_funding_by_secret_eth() { maker_secret_hash: &maker_secret_hash, dex_fee, premium_amount: Default::default(), - trading_amount: 1.into(), + trading_amount, swap_unique_data: &[], watcher_reward: false, }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx_refund = block_on(taker_coin.refund_taker_funding_secret(refund_args)).unwrap(); log!( "Taker refunded ETH funding by secret, tx hash: {:02x}", @@ -1619,9 +1709,8 @@ fn send_and_refund_taker_funding_by_secret_eth() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); - let balance_after_refund = check_eth_balance(taker_address); + let balance_after_refund = sepolia_check_eth_balance(taker_address); log!("Taker ETH balance after refund: {}", balance_after_refund); - assert_eq!(balance_before_payment, balance_after_refund); } #[test] @@ -1638,7 +1727,6 @@ fn send_and_refund_taker_funding_by_secret_erc20() { let payment_time_lock = now_sec() + 1000; let taker_address = block_on(taker_coin.my_addr()); - log!("taker_address type: {:?}", taker_address); log!("coin type: {:?}", taker_coin.coin_type); let balance_before_payment = check_erc20_balance(taker_address); @@ -1658,7 +1746,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { premium_amount: BigDecimal::default(), trading_amount: 1.into(), swap_unique_data: &[], - wait_for_confirmation_until: now_sec() + 80, + wait_for_confirmation_until: now_sec() + 100, }; let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); @@ -1694,14 +1782,12 @@ fn send_and_refund_taker_funding_by_secret_erc20() { let balance_after_refund = check_erc20_balance(taker_address); log!("Taker ERC20 balance after refund: {}", balance_after_refund); - assert_eq!(balance_before_payment, balance_after_refund); } -#[ignore] #[test] fn send_and_refund_taker_funding_timelock_eth() { - let taker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init(), false); - let maker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init(), false); + let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf()); + let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf()); let taker_secret = vec![0; 32]; let taker_secret_hash = sha256(&taker_secret).to_vec(); @@ -1709,8 +1795,9 @@ fn send_and_refund_taker_funding_timelock_eth() { let maker_secret_hash = sha256(&maker_secret).to_vec(); let taker_address = block_on(taker_coin.my_addr()); + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); - let balance_before_payment = check_eth_balance(taker_address); + let balance_before_payment = sepolia_check_eth_balance(taker_address); log!("Taker ETH balance before payment: {}", balance_before_payment); // exceed funding_time_lock, as if TakerPaymentState.PaymentSent then timestamp should exceed payment pre-approve lock time @@ -1718,7 +1805,9 @@ fn send_and_refund_taker_funding_timelock_eth() { // TODO need to impl taker approve to test exceeded payment_time_lock let payment_time_lock = now_sec() + 1000; - let dex_fee = &DexFee::Standard("0.1".into()); + let dex_fee = &DexFee::Standard("0.00001".into()); + let trading_amount = BigDecimal::from_str("0.0001").unwrap(); + let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); let payment_args = SendTakerFundingArgs { funding_time_lock, @@ -1728,7 +1817,7 @@ fn send_and_refund_taker_funding_timelock_eth() { maker_pub: maker_pub.as_bytes(), dex_fee, premium_amount: BigDecimal::default(), - trading_amount: 1.into(), + trading_amount: trading_amount.clone(), swap_unique_data: &[], wait_for_confirmation_until: 0, }; @@ -1737,7 +1826,7 @@ fn send_and_refund_taker_funding_timelock_eth() { wait_for_confirmations(&taker_coin, &funding_tx, 100); - let balance_after_payment = check_eth_balance(taker_address); + let balance_after_payment = sepolia_check_eth_balance(taker_address); log!("Taker ETH balance after payment: {}", balance_after_payment); let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { @@ -1754,8 +1843,9 @@ fn send_and_refund_taker_funding_timelock_eth() { watcher_reward: false, dex_fee, premium_amount: BigDecimal::default(), - trading_amount: 1.into(), + trading_amount, }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx_refund = block_on(taker_coin.refund_taker_funding_timelock(refund_args)).unwrap(); log!( "Taker refunded ETH funding after pre-approval lock time was exceeded, tx hash: {:02x}", @@ -1764,9 +1854,8 @@ fn send_and_refund_taker_funding_timelock_eth() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); - let balance_after_refund = check_eth_balance(taker_address); + let balance_after_refund = sepolia_check_eth_balance(taker_address); log!("Taker ETH balance after refund: {}", balance_after_refund); - assert_eq!(balance_before_payment, balance_after_refund); } #[ignore] @@ -1839,5 +1928,4 @@ fn send_and_refund_taker_funding_timelock_erc20() { let balance_after_refund = check_erc20_balance(taker_address); log!("Taker ERC20 balance after refund: {}", balance_after_refund); - assert_eq!(balance_before_payment, balance_after_refund); } From fd504b10a8dcc2ae43107fcb761709a46ae16182 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 24 Jul 2024 18:50:45 +0700 Subject: [PATCH 128/233] remove balance logs --- .../tests/docker_tests/eth_docker_tests.rs | 46 +------------------ 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 872bf1cfe1..1413afbf7a 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -185,6 +185,7 @@ fn sepolia_check_eth_balance(address: Address) -> U256 { block_on(SEPOLIA_WEB3.eth().balance(address, None)).unwrap() } +#[allow(dead_code)] fn check_erc20_balance(address: Address) -> U256 { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc20_contract = Contract::from_json(GETH_WEB3.eth(), erc20_contract(), ERC20_ABI.as_bytes()).unwrap(); @@ -1659,9 +1660,6 @@ fn send_and_refund_taker_funding_by_secret_eth() { let taker_address = block_on(taker_coin.my_addr()); wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); - let balance_before_payment = sepolia_check_eth_balance(taker_address); - log!("Taker ETH balance before payment: {}", balance_before_payment); - let dex_fee = &DexFee::Standard("0.00001".into()); let trading_amount = BigDecimal::from_str("0.0001").unwrap(); @@ -1683,9 +1681,6 @@ fn send_and_refund_taker_funding_by_secret_eth() { wait_for_confirmations(&taker_coin, &funding_tx, 100); - let balance_after_payment = sepolia_check_eth_balance(taker_address); - log!("Taker ETH balance after payment: {}", balance_after_payment); - let refund_args = RefundFundingSecretArgs { funding_tx: &funding_tx, funding_time_lock, @@ -1708,9 +1703,6 @@ fn send_and_refund_taker_funding_by_secret_eth() { ); wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); - - let balance_after_refund = sepolia_check_eth_balance(taker_address); - log!("Taker ETH balance after refund: {}", balance_after_refund); } #[test] @@ -1726,14 +1718,6 @@ fn send_and_refund_taker_funding_by_secret_erc20() { let funding_time_lock = now_sec() + 3000; let payment_time_lock = now_sec() + 1000; - let taker_address = block_on(taker_coin.my_addr()); - log!("coin type: {:?}", taker_coin.coin_type); - - let balance_before_payment = check_erc20_balance(taker_address); - log!("Taker ERC20 balance before payment: {}", balance_before_payment); - let eth_before_payment = check_eth_balance(taker_address); - log!("Taker ETH balance before payment: {}", eth_before_payment); - let dex_fee = &DexFee::Standard("0.1".into()); let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); let payment_args = SendTakerFundingArgs { @@ -1754,11 +1738,6 @@ fn send_and_refund_taker_funding_by_secret_erc20() { wait_for_confirmations(&taker_coin, &funding_tx, 100); - let balance_after_payment = check_erc20_balance(taker_address); - log!("Taker ERC20 balance after payment: {}", balance_after_payment); - let eth_after_payment = check_eth_balance(taker_address); - log!("Taker ETH balance after payment: {}", eth_after_payment); - let refund_args = RefundFundingSecretArgs { funding_tx: &funding_tx, funding_time_lock, @@ -1779,9 +1758,6 @@ fn send_and_refund_taker_funding_by_secret_erc20() { funding_tx_refund.tx_hash() ); wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); - - let balance_after_refund = check_erc20_balance(taker_address); - log!("Taker ERC20 balance after refund: {}", balance_after_refund); } #[test] @@ -1797,9 +1773,6 @@ fn send_and_refund_taker_funding_timelock_eth() { let taker_address = block_on(taker_coin.my_addr()); wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); - let balance_before_payment = sepolia_check_eth_balance(taker_address); - log!("Taker ETH balance before payment: {}", balance_before_payment); - // exceed funding_time_lock, as if TakerPaymentState.PaymentSent then timestamp should exceed payment pre-approve lock time let funding_time_lock = now_sec() - 3000; // TODO need to impl taker approve to test exceeded payment_time_lock @@ -1826,9 +1799,6 @@ fn send_and_refund_taker_funding_timelock_eth() { wait_for_confirmations(&taker_coin, &funding_tx, 100); - let balance_after_payment = sepolia_check_eth_balance(taker_address); - log!("Taker ETH balance after payment: {}", balance_after_payment); - let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash: &maker_secret_hash, taker_secret_hash: &taker_secret_hash, @@ -1853,9 +1823,6 @@ fn send_and_refund_taker_funding_timelock_eth() { ); wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); - - let balance_after_refund = sepolia_check_eth_balance(taker_address); - log!("Taker ETH balance after refund: {}", balance_after_refund); } #[ignore] @@ -1871,11 +1838,6 @@ fn send_and_refund_taker_funding_timelock_erc20() { let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); - let taker_address = block_on(taker_coin.my_addr()); - - let balance_before_payment = check_erc20_balance(taker_address); - log!("Taker ERC20 balance before payment: {}", balance_before_payment); - // exceed funding_time_lock, as if TakerPaymentState.PaymentSent then timestamp should exceed payment pre-approve lock time let funding_time_lock = now_sec() - 3000; // TODO need to impl taker approve to test exceeded payment_time_lock @@ -1900,9 +1862,6 @@ fn send_and_refund_taker_funding_timelock_erc20() { wait_for_confirmations(&taker_coin, &funding_tx, 100); - let balance_after_payment = check_erc20_balance(taker_address); - log!("Taker ERC20 balance after payment: {}", balance_after_payment); - let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash: &maker_secret_hash, taker_secret_hash: &taker_secret_hash, @@ -1925,7 +1884,4 @@ fn send_and_refund_taker_funding_timelock_erc20() { funding_tx_refund.tx_hash() ); wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); - - let balance_after_refund = check_erc20_balance(taker_address); - log!("Taker ERC20 balance after refund: {}", balance_after_refund); } From c629d7a1a736ff30699c74b4da663ad38b8c7fb5 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 25 Jul 2024 17:18:38 +0700 Subject: [PATCH 129/233] review: provide eth total payment to sign_and_send_transaction --- mm2src/coins/eth/eth_swap_v2.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 352a72d0f3..d91194b069 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -30,7 +30,7 @@ impl EthCoin { let dex_fee = try_tx_s!(wei_from_big_decimal(&args.dex_fee.fee_amount().into(), self.decimals)); let payment_amount = try_tx_s!(wei_from_big_decimal( - &(args.trading_amount + args.premium_amount), + &(args.trading_amount.clone() + args.premium_amount.clone()), self.decimals )); let maker_address = try_tx_s!(addr_from_raw_pubkey(args.maker_pub)); @@ -50,8 +50,12 @@ impl EthCoin { match &self.coin_type { EthCoinType::Eth => { let data = try_tx_s!(self.prepare_taker_eth_funding_data(&funding_args).await); + let eth_total_payment = try_tx_s!(wei_from_big_decimal( + &(args.dex_fee.fee_amount().to_decimal() + args.trading_amount + args.premium_amount), + self.decimals + )); self.sign_and_send_transaction( - payment_amount, + eth_total_payment, Action::Call(taker_swap_v2_contract), data, U256::from(self.gas_limit.eth_payment), From ed08df9ff8434245cb445fc3a49cade2b21f9db4 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 25 Jul 2024 17:32:09 +0700 Subject: [PATCH 130/233] review: fix typo --- mm2src/coins/lp_coins.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 7d7bf1dac8..4903aa41be 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1651,7 +1651,7 @@ pub struct RefundMakerPaymentArgs<'a, Coin: ParseCoinAssocTypes + ?Sized> { pub swap_unique_data: &'a [u8], } -/// Commont refund NFT Maker Payment structure for [MakerNftSwapOpsV2::refund_nft_maker_payment_v2_timelock] and +/// Common refund NFT Maker Payment structure for [MakerNftSwapOpsV2::refund_nft_maker_payment_v2_timelock] and /// [MakerNftSwapOpsV2::refund_nft_maker_payment_v2_secret] methods pub struct RefundNftMakerPaymentArgs<'a, Coin: ParseCoinAssocTypes + ParseNftAssocTypes + ?Sized> { /// Maker payment tx From 89e543f894b7257a623bcee39f623137ebec414f Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 25 Jul 2024 17:40:53 +0700 Subject: [PATCH 131/233] review: update log to "Sent taker funding spend (taker payment)" --- mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs index ac5edf9312..cb0dd43efe 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs @@ -1573,7 +1573,7 @@ impl Date: Thu, 25 Jul 2024 17:42:41 +0700 Subject: [PATCH 132/233] allow check_eth_balance dead code in docker tests --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 1413afbf7a..5c3f0f7b9b 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -174,6 +174,7 @@ fn fill_erc20(to_addr: Address, amount: U256) { wait_for_confirmation(tx_hash); } +#[allow(dead_code)] fn check_eth_balance(address: Address) -> U256 { let _guard = GETH_NONCE_LOCK.lock().unwrap(); block_on(GETH_WEB3.eth().balance(address, None)).unwrap() From 28bc18ac36604a69690693b432ad5ec50783f0f4 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 25 Jul 2024 20:04:18 +0700 Subject: [PATCH 133/233] review: remove legacy "derive_htlc_pubkey" function from swap_v2, use derive_htlc_pubkey_v2_bytes instead --- mm2src/coins/eth.rs | 7 +++++ mm2src/coins/lp_coins.rs | 9 +++++-- mm2src/coins/test_coin.rs | 8 ++++-- mm2src/coins/utxo/utxo_standard.rs | 9 ++++++- mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs | 4 +-- mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 4 +-- .../tests/docker_tests/eth_docker_tests.rs | 26 +++++++------------ 7 files changed, 42 insertions(+), 25 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index a4d6b39e12..ac79798779 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7180,7 +7180,9 @@ impl TakerCoinSwapOpsV2 for EthCoin { ) -> MmResult { todo!() } +} +impl CommonSwapOpsV2 for EthCoin { #[inline(always)] fn derive_htlc_pubkey_v2(&self, _swap_unique_data: &[u8]) -> Self::Pubkey { match self.priv_key_policy { @@ -7201,4 +7203,9 @@ impl TakerCoinSwapOpsV2 for EthCoin { }, } } + + #[inline(always)] + fn derive_htlc_pubkey_v2_bytes(&self, swap_unique_data: &[u8]) -> Vec { + self.derive_htlc_pubkey_v2(swap_unique_data).to_bytes() + } } diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 4903aa41be..f6a861ca6d 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1708,7 +1708,7 @@ pub struct SpendNftMakerPaymentArgs<'a, Coin: ParseCoinAssocTypes + ParseNftAsso /// Operations specific to maker coin in [Trading Protocol Upgrade implementation](https://github.com/KomodoPlatform/komodo-defi-framework/issues/1895) #[async_trait] -pub trait MakerCoinSwapOpsV2: ParseCoinAssocTypes + Send + Sync + 'static { +pub trait MakerCoinSwapOpsV2: ParseCoinAssocTypes + CommonSwapOpsV2 + Send + Sync + 'static { /// Generate and broadcast maker payment transaction async fn send_maker_payment_v2(&self, args: SendMakerPaymentArgs<'_, Self>) -> Result; @@ -1842,7 +1842,7 @@ pub enum SearchForFundingSpendErr { /// Operations specific to taker coin in [Trading Protocol Upgrade implementation](https://github.com/KomodoPlatform/komodo-defi-framework/issues/1895) #[async_trait] -pub trait TakerCoinSwapOpsV2: ParseCoinAssocTypes + Send + Sync + 'static { +pub trait TakerCoinSwapOpsV2: ParseCoinAssocTypes + CommonSwapOpsV2 + Send + Sync + 'static { /// Generate and broadcast taker funding transaction that includes dex fee, maker premium and actual trading volume. /// Funding tx can be reclaimed immediately if maker back-outs (doesn't send maker payment) async fn send_taker_funding(&self, args: SendTakerFundingArgs<'_>) -> Result; @@ -1923,9 +1923,14 @@ pub trait TakerCoinSwapOpsV2: ParseCoinAssocTypes + Send + Sync + 'static { from_block: u64, wait_until: u64, ) -> MmResult; +} +#[async_trait] +pub trait CommonSwapOpsV2: ParseCoinAssocTypes + Send + Sync + 'static { /// Derives an HTLC key-pair and returns a public key corresponding to that key. fn derive_htlc_pubkey_v2(&self, swap_unique_data: &[u8]) -> Self::Pubkey; + + fn derive_htlc_pubkey_v2_bytes(&self, swap_unique_data: &[u8]) -> Vec; } /// Operations that coins have independently from the MarketMaker. diff --git a/mm2src/coins/test_coin.rs b/mm2src/coins/test_coin.rs index c077bf60bd..a5eaff2220 100644 --- a/mm2src/coins/test_coin.rs +++ b/mm2src/coins/test_coin.rs @@ -1,6 +1,6 @@ #![allow(clippy::all)] -use super::{CoinBalance, FundingTxSpend, HistorySyncState, MarketCoinOps, MmCoin, RawTransactionFut, +use super::{CoinBalance, CommonSwapOpsV2, FundingTxSpend, HistorySyncState, MarketCoinOps, MmCoin, RawTransactionFut, RawTransactionRequest, SearchForFundingSpendErr, SwapOps, TradeFee, TransactionEnum, TransactionFut, WaitForTakerPaymentSpendError}; use crate::coin_errors::ValidatePaymentResult; @@ -555,6 +555,10 @@ impl TakerCoinSwapOpsV2 for TestCoin { ) -> MmResult { unimplemented!() } +} + +impl CommonSwapOpsV2 for TestCoin { + fn derive_htlc_pubkey_v2(&self, _swap_unique_data: &[u8]) -> Self::Pubkey { todo!() } - fn derive_htlc_pubkey_v2(&self, swap_unique_data: &[u8]) -> Self::Pubkey { todo!() } + fn derive_htlc_pubkey_v2_bytes(&self, _swap_unique_data: &[u8]) -> Vec { todo!() } } diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index 75dfb5391a..6baaf9d180 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -23,7 +23,7 @@ use crate::utxo::utxo_hd_wallet::{UtxoHDAccount, UtxoHDAddress}; use crate::utxo::utxo_tx_history_v2::{UtxoMyAddressesHistoryError, UtxoTxDetailsError, UtxoTxDetailsParams, UtxoTxHistoryOps}; use crate::{CanRefundHtlc, CheckIfMyPaymentSentArgs, CoinBalance, CoinWithDerivationMethod, CoinWithPrivKeyPolicy, - ConfirmPaymentInput, DexFee, FundingTxSpend, GenPreimageResult, GenTakerFundingSpendArgs, + CommonSwapOpsV2, ConfirmPaymentInput, DexFee, FundingTxSpend, GenPreimageResult, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, GetWithdrawSenderAddress, IguanaBalanceOps, IguanaPrivKey, MakerCoinSwapOpsV2, MakerSwapTakerCoin, MmCoinEnum, NegotiateSwapContractAddrErr, PaymentInstructionArgs, PaymentInstructions, PaymentInstructionsErr, PrivKeyBuildPolicy, RawTransactionRequest, RawTransactionResult, RefundError, @@ -824,10 +824,17 @@ impl TakerCoinSwapOpsV2 for UtxoStandardCoin { .await?; Ok(res) } +} +impl CommonSwapOpsV2 for UtxoStandardCoin { fn derive_htlc_pubkey_v2(&self, swap_unique_data: &[u8]) -> Self::Pubkey { *self.derive_htlc_key_pair(swap_unique_data).public() } + + #[inline(always)] + fn derive_htlc_pubkey_v2_bytes(&self, swap_unique_data: &[u8]) -> Vec { + self.derive_htlc_pubkey_v2(swap_unique_data).to_bytes() + } } #[async_trait] diff --git a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs index 6e9555c10f..23f5e82259 100644 --- a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs @@ -903,8 +903,8 @@ impl SignedEthTx { - let taker_pubkey = setup.taker_global_nft.derive_htlc_pubkey(&[]); let nft_swap_info = NftSwapInfo { token_address: &setup.nft_swap_info.token_address, token_id: &setup.nft_swap_info.token_id, @@ -1310,7 +1309,7 @@ fn send_nft_maker_payment(setup: &NftTestSetup, amount: BigDecimal) -> SignedEth taker_secret_hash: &setup.taker_secret_hash, maker_secret_hash: &setup.maker_secret_hash, amount, - taker_pub: &setup.taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), + taker_pub: &setup.taker_global_nft.derive_htlc_pubkey_v2(&[]), swap_unique_data: &[], nft_swap_info: &nft_swap_info, }; @@ -1329,8 +1328,6 @@ fn wait_for_confirmations(global_nft: &EthCoin, tx: &SignedEthTx, wait_seconds: } fn validate_nft_maker_payment(setup: &NftTestSetup, maker_payment: &SignedEthTx, amount: BigDecimal) { - let maker_pubkey = setup.maker_global_nft.derive_htlc_pubkey(&[]); - let taker_pubkey = setup.taker_global_nft.derive_htlc_pubkey(&[]); let nft_swap_info = NftSwapInfo { token_address: &setup.nft_swap_info.token_address, token_id: &setup.nft_swap_info.token_id, @@ -1343,8 +1340,8 @@ fn validate_nft_maker_payment(setup: &NftTestSetup, maker_payment: &SignedEthTx, taker_secret_hash: &setup.taker_secret_hash, maker_secret_hash: &setup.maker_secret_hash, amount, - taker_pub: &setup.taker_global_nft.parse_pubkey(&taker_pubkey).unwrap(), - maker_pub: &setup.maker_global_nft.parse_pubkey(&maker_pubkey).unwrap(), + taker_pub: &setup.taker_global_nft.derive_htlc_pubkey_v2(&[]), + maker_pub: &setup.maker_global_nft.derive_htlc_pubkey_v2(&[]), swap_unique_data: &[], nft_swap_info: &nft_swap_info, }; @@ -1361,10 +1358,7 @@ fn spend_nft_maker_payment( taker_secret_hash: &setup.taker_secret_hash, maker_secret_hash: &setup.maker_secret_hash, maker_secret: &setup.maker_secret, - maker_pub: &setup - .maker_global_nft - .parse_pubkey(&setup.maker_global_nft.derive_htlc_pubkey(&[])) - .unwrap(), + maker_pub: &setup.maker_global_nft.derive_htlc_pubkey_v2(&[]), swap_unique_data: &[], contract_type, swap_contract_address: &setup.nft_swap_info.swap_contract_address, From 173dd33a9dd33ede73eb8854630a271bd87cd050 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 25 Jul 2024 20:15:48 +0700 Subject: [PATCH 134/233] fmt code --- .../tests/docker_tests/eth_docker_tests.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 8d8b23e3f0..395875ef67 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -12,13 +12,13 @@ use coins::eth::v2_activation::{eth_coin_from_conf_and_request_v2, EthActivation use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_request, EthCoin, EthCoinType, EthPrivKeyBuildPolicy, SignedEthTx, SwapV2Contracts, ERC20_ABI}; use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; -use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, ConfirmPaymentInput, DerivationMethod, - DexFee, Eip1559Ops, FoundSwapTxSpend, MakerNftSwapOpsV2, MarketCoinOps, MmCoinEnum, MmCoinStruct, - NftSwapInfo, ParseCoinAssocTypes, ParseNftAssocTypes, PrivKeyBuildPolicy, RefundFundingSecretArgs, - RefundNftMakerPaymentArgs, RefundPaymentArgs, RefundTakerPaymentArgs, SearchForSwapTxSpendInput,MmCoinStruct, - SendNftMakerPaymentArgs, SendPaymentArgs, SendTakerFundingArgs, SpendNftMakerPaymentArgs, - SpendPaymentArgs, SwapOps, SwapTxFeePolicy, SwapTxTypeWithSecretHash, TakerCoinSwapOpsV2, ToBytes,CommonSwapOpsV2, - Transaction, ValidateNftMakerPaymentArgs}; +use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, CommonSwapOpsV2, ConfirmPaymentInput, + DerivationMethod, DexFee, Eip1559Ops, FoundSwapTxSpend, MakerNftSwapOpsV2, MarketCoinOps, MmCoinEnum, + MmCoinStruct, NftSwapInfo, ParseCoinAssocTypes, ParseNftAssocTypes, PrivKeyBuildPolicy, + RefundFundingSecretArgs, RefundNftMakerPaymentArgs, RefundPaymentArgs, RefundTakerPaymentArgs, + SearchForSwapTxSpendInput, SendNftMakerPaymentArgs, SendPaymentArgs, SendTakerFundingArgs, + SpendNftMakerPaymentArgs, SpendPaymentArgs, SwapOps, SwapTxFeePolicy, SwapTxTypeWithSecretHash, + TakerCoinSwapOpsV2, ToBytes, Transaction, ValidateNftMakerPaymentArgs}; use common::{block_on, now_sec}; use crypto::Secp256k1Secret; use ethcore_transaction::Action; From 7570df79cbb1ce29c0d24285e112726578fb4e47 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 26 Jul 2024 11:45:41 +0700 Subject: [PATCH 135/233] gas limit: TODO about new consts and params for v2 calls --- mm2src/coins/eth/eth_swap_v2.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index d91194b069..ee3c39f550 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -58,6 +58,7 @@ impl EthCoin { eth_total_payment, Action::Call(taker_swap_v2_contract), data, + // TODO need new consts and params for v2 calls. now it uses v1 U256::from(self.gas_limit.eth_payment), ) .compat() @@ -93,6 +94,7 @@ impl EthCoin { U256::from(0), Action::Call(taker_swap_v2_contract), data, + // TODO need new consts and params for v2 calls. now it uses v1 U256::from(self.gas_limit.erc20_payment), ) .compat() @@ -102,6 +104,7 @@ impl EthCoin { U256::from(0), Action::Call(taker_swap_v2_contract), data, + // TODO need new consts and params for v2 calls. now it uses v1 U256::from(self.gas_limit.erc20_payment), ) .compat() From 3042e604ad4cf40c8fcd932b75fb0054b311b856 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 26 Jul 2024 12:23:05 +0700 Subject: [PATCH 136/233] todo burnFee support --- mm2src/coins/eth/eth_swap_v2.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index ee3c39f550..c6ac33d302 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -27,6 +27,7 @@ impl EthCoin { .as_ref() .map(|contracts| contracts.taker_swap_v2_contract) .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; + // TODO add burnFee support let dex_fee = try_tx_s!(wei_from_big_decimal(&args.dex_fee.fee_amount().into(), self.decimals)); let payment_amount = try_tx_s!(wei_from_big_decimal( From e1e22422052c2c2c338d0f848506095b8429d6a8 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 26 Jul 2024 12:44:06 +0700 Subject: [PATCH 137/233] review: update doc comments for taker and maker secret hashes in SendTakerFundingArgs struct --- mm2src/coins/lp_coins.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index f6a861ca6d..39d2bc0b33 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1283,9 +1283,9 @@ pub struct SendTakerFundingArgs<'a> { pub funding_time_lock: u64, /// The timestamp after which the taker can refund the payment transaction if the maker hasn't claimed it by revealing their secret pub payment_time_lock: u64, - /// The hash of the secret generated by the taker, needed to reveal for immediate refund + /// The hash of the secret generated by the taker, needed for immediate refund pub taker_secret_hash: &'a [u8], - /// The hash of the secret generated by the maker, needed to reveal to spend the payment + /// The hash of the secret generated by the maker, needed to spend the payment pub maker_secret_hash: &'a [u8], /// Maker's pubkey pub maker_pub: &'a [u8], From fcd394d0911e29815a140c50acbaf81c6263a0cc Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 26 Jul 2024 13:16:26 +0700 Subject: [PATCH 138/233] review: specify timelock doc comments for UTXO and smart contracts in SendTakerFundingArgs struct --- mm2src/coins/lp_coins.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 39d2bc0b33..921ccc92f3 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1279,9 +1279,10 @@ pub trait WatcherOps { /// Helper struct wrapping arguments for [TakerCoinSwapOpsV2::send_taker_funding] pub struct SendTakerFundingArgs<'a> { - /// The timestamp after which the taker can refund the funding transaction if the maker hasn't pre-approved the transaction + /// For UTXO-based coins, the taker can refund the funding after this timestamp if the maker hasn't claimed it. + /// For smart contracts, the taker can refund the payment after this timestamp if the maker hasn't pre-approved the transaction. pub funding_time_lock: u64, - /// The timestamp after which the taker can refund the payment transaction if the maker hasn't claimed it by revealing their secret + /// For smart contracts, the taker can refund the payment after this timestamp if the maker hasn't claimed it by revealing their secret. pub payment_time_lock: u64, /// The hash of the secret generated by the taker, needed for immediate refund pub taker_secret_hash: &'a [u8], From 6a231a3dfa7bc42d5040f1394bbe55e0c27809b0 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 26 Jul 2024 13:33:12 +0700 Subject: [PATCH 139/233] review: remove wait_for_confirmation_until and use funding_time_lock for erc20 approve --- mm2src/coins/eth/eth_swap_v2.rs | 24 ++++++++----------- mm2src/coins/lp_coins.rs | 3 +-- mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 2 -- .../tests/docker_tests/swap_proto_v2_tests.rs | 5 ---- 4 files changed, 11 insertions(+), 23 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index c6ac33d302..b5f6a0733e 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -77,20 +77,16 @@ impl EthCoin { let data = try_tx_s!(self.prepare_taker_erc20_funding_data(&funding_args, *token_addr).await); if allowed < payment_amount { let approved_tx = self.approve(taker_swap_v2_contract, U256::max_value()).compat().await?; - self.wait_for_required_allowance( - taker_swap_v2_contract, - payment_amount, - args.wait_for_confirmation_until, - ) - .compat() - .await - .map_err(|e| { - TransactionErr::Plain(ERRL!( - "Allowed value was not updated in time after sending approve transaction {:02x}: {}", - approved_tx.tx_hash_as_bytes(), - e - )) - })?; + self.wait_for_required_allowance(taker_swap_v2_contract, payment_amount, args.funding_time_lock) + .compat() + .await + .map_err(|e| { + TransactionErr::Plain(ERRL!( + "Allowed value was not updated in time after sending approve transaction {:02x}: {}", + approved_tx.tx_hash_as_bytes(), + e + )) + })?; self.sign_and_send_transaction( U256::from(0), Action::Call(taker_swap_v2_contract), diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 921ccc92f3..4e5d281b33 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1281,6 +1281,7 @@ pub trait WatcherOps { pub struct SendTakerFundingArgs<'a> { /// For UTXO-based coins, the taker can refund the funding after this timestamp if the maker hasn't claimed it. /// For smart contracts, the taker can refund the payment after this timestamp if the maker hasn't pre-approved the transaction. + /// This field is additionally used to wait for confirmations of ERC20 approval transaction. pub funding_time_lock: u64, /// For smart contracts, the taker can refund the payment after this timestamp if the maker hasn't claimed it by revealing their secret. pub payment_time_lock: u64, @@ -1298,8 +1299,6 @@ pub struct SendTakerFundingArgs<'a> { pub trading_amount: BigDecimal, /// Unique data of specific swap pub swap_unique_data: &'a [u8], - /// As of now, this field is specifically used to wait for confirmations of ERC20 approval transaction. - pub wait_for_confirmation_until: u64, } /// Helper struct wrapping arguments for [TakerCoinSwapOpsV2::refund_taker_funding_secret] diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs index 3c3052c39a..278c5ffe75 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs @@ -1230,8 +1230,6 @@ impl Date: Fri, 26 Jul 2024 13:36:45 +0700 Subject: [PATCH 140/233] todo note about gas_limit params for v2 calls --- mm2src/coins/eth/eth_swap_v2.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 2c0b9bcb13..f0c2b51207 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -178,10 +178,12 @@ impl EthCoin { }; let (token_address, gas_limit) = match &self.coin_type { + // TODO need new consts and params for v2 calls. now it uses v1 EthCoinType::Eth => (Address::default(), self.gas_limit.eth_sender_refund), EthCoinType::Erc20 { platform: _, token_addr, + // TODO need new consts and params for v2 calls. now it uses v1 } => (*token_addr, self.gas_limit.erc20_sender_refund), EthCoinType::Nft { .. } => { return Err(TransactionErr::ProtocolNotSupported( @@ -232,10 +234,12 @@ impl EthCoin { let maker_address = public_to_address(args.maker_pubkey); let payment_time_lock: u32 = try_tx_s!(args.payment_time_lock.try_into()); let (token_address, gas_limit) = match &self.coin_type { + // TODO need new consts and params for v2 calls. now it uses v1 EthCoinType::Eth => (Address::default(), self.gas_limit.eth_sender_refund), EthCoinType::Erc20 { platform: _, token_addr, + // TODO need new consts and params for v2 calls. now it uses v1 } => (*token_addr, self.gas_limit.erc20_sender_refund), EthCoinType::Nft { .. } => { return Err(TransactionErr::ProtocolNotSupported( From e7802803069b86c9dfa416700de24ff2585d0b75 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 26 Jul 2024 13:51:37 +0700 Subject: [PATCH 141/233] fix clippy and provide sleep duration to test pre-approved timelock using funding_time_lock --- .../mm2_main/tests/docker_tests/eth_docker_tests.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 395875ef67..11d91914ea 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1669,7 +1669,6 @@ fn send_and_refund_taker_funding_by_secret_eth() { premium_amount: BigDecimal::default(), trading_amount: trading_amount.clone(), swap_unique_data: &[], - wait_for_confirmation_until: 0, }; let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); @@ -1725,7 +1724,6 @@ fn send_and_refund_taker_funding_by_secret_erc20() { premium_amount: BigDecimal::default(), trading_amount: 1.into(), swap_unique_data: &[], - wait_for_confirmation_until: now_sec() + 100, }; let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); @@ -1768,7 +1766,7 @@ fn send_and_refund_taker_funding_timelock_eth() { let taker_address = block_on(taker_coin.my_addr()); wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); - // exceed funding_time_lock, as if TakerPaymentState.PaymentSent then timestamp should exceed payment pre-approve lock time + // if TakerPaymentState is `PaymentSent` then timestamp should exceed payment pre-approve lock time (funding_time_lock) let funding_time_lock = now_sec() - 3000; // TODO need to impl taker approve to test exceeded payment_time_lock let payment_time_lock = now_sec() + 1000; @@ -1787,7 +1785,6 @@ fn send_and_refund_taker_funding_timelock_eth() { premium_amount: BigDecimal::default(), trading_amount: trading_amount.clone(), swap_unique_data: &[], - wait_for_confirmation_until: 0, }; let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); @@ -1823,7 +1820,6 @@ fn send_and_refund_taker_funding_timelock_eth() { #[ignore] #[test] fn send_and_refund_taker_funding_timelock_erc20() { - thread::sleep(Duration::from_secs(2)); let erc20_conf = &erc20_dev_conf(&erc20_contract_checksum()); let taker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init(), true); let maker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init(), true); @@ -1833,8 +1829,8 @@ fn send_and_refund_taker_funding_timelock_erc20() { let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); - // exceed funding_time_lock, as if TakerPaymentState.PaymentSent then timestamp should exceed payment pre-approve lock time - let funding_time_lock = now_sec() - 3000; + // if TakerPaymentState is `PaymentSent` then timestamp should exceed payment pre-approve lock time (funding_time_lock) + let funding_time_lock = now_sec() + 29; // TODO need to impl taker approve to test exceeded payment_time_lock let payment_time_lock = now_sec() + 1000; @@ -1850,12 +1846,12 @@ fn send_and_refund_taker_funding_timelock_erc20() { premium_amount: BigDecimal::default(), trading_amount: 1.into(), swap_unique_data: &[], - wait_for_confirmation_until: now_sec() + 60, }; let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); wait_for_confirmations(&taker_coin, &funding_tx, 100); + thread::sleep(Duration::from_secs(30)); let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash: &maker_secret_hash, From 847330429f4d190672d82e22d111e8fd1a704366 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 28 Jul 2024 17:21:29 +0700 Subject: [PATCH 142/233] erc20 tests on sepolia --- .../tests/docker_tests/docker_tests_common.rs | 3 +- .../tests/docker_tests/eth_docker_tests.rs | 74 +++++++++++++------ mm2src/mm2_test_helpers/src/for_tests.rs | 19 +++++ 3 files changed, 72 insertions(+), 24 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index d1b3ae508d..18c97ad3d8 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -1671,8 +1671,7 @@ pub fn init_geth_node() { SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2 = EthAddress::from_str("0x9eb88cd58605d8fb9b14652d6152727f7e95fb4d").unwrap(); SEPOLIA_ERC721_CONTRACT = EthAddress::from_str("0xbac1c9f2087f39caaa4e93412c6412809186870e").unwrap(); SEPOLIA_ERC1155_CONTRACT = EthAddress::from_str("0xfb53b8764be6033d89ceacafa36631b09d60a1d2").unwrap(); - // TODO update this - SEPOLIA_ERC20_CONTRACT = EthAddress::from_str("0x7Cc9F2c1c3B797D09B9d1CCd7FDcD2539a4b3874").unwrap(); + SEPOLIA_ERC20_CONTRACT = EthAddress::from_str("0xF7b5F8E8555EF7A743f24D3E974E23A3C6cB6638").unwrap(); SEPOLIA_TAKER_SWAP_V2 = EthAddress::from_str("0x7Cc9F2c1c3B797D09B9d1CCd7FDcD2539a4b3874").unwrap(); // TODO update this SEPOLIA_MAKER_SWAP_V2 = EthAddress::from_str("0x7Cc9F2c1c3B797D09B9d1CCd7FDcD2539a4b3874").unwrap(); diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 11d91914ea..923cd729c1 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -26,7 +26,8 @@ use ethereum_types::U256; use futures01::Future; use mm2_core::mm_ctx::MmArc; use mm2_number::{BigDecimal, BigUint}; -use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, eth_sepolia_conf, nft_dev_conf, nft_sepolia_conf}; +use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, eth_sepolia_conf, nft_dev_conf, nft_sepolia_conf, + seploia_erc20_dev_conf}; use serde_json::Value as Json; use std::str::FromStr; use std::thread; @@ -519,7 +520,7 @@ fn global_nft_from_privkey( #[allow(dead_code)] /// Can be used to generate coin from Sepolia Maker/Taker priv keys. -fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, conf: &Json) -> EthCoin { +fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, conf: &Json, erc20: bool) -> EthCoin { let swap_addr = SwapAddresses { swap_v2_contracts: SwapV2Contracts { maker_swap_v2_contract: sepolia_maker_swap_v2(), @@ -560,6 +561,15 @@ fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, co build_policy, )) .unwrap(); + let coin = if erc20 { + let coin_type = EthCoinType::Erc20 { + platform: ETH.to_string(), + token_addr: sepolia_erc20_contract(), + }; + block_on(coin.set_coin_type(coin_type)) + } else { + coin + }; let coins_ctx = CoinsContext::from_ctx(ctx).unwrap(); let mut coins = block_on(coins_ctx.lock_coins()); @@ -571,9 +581,9 @@ fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, co } #[allow(dead_code)] -fn get_or_create_sepolia_coin(ctx: &MmArc, priv_key: &'static str, ticker: &str, conf: &Json) -> EthCoin { +fn get_or_create_sepolia_coin(ctx: &MmArc, priv_key: &'static str, ticker: &str, conf: &Json, erc20: bool) -> EthCoin { match block_on(lp_coinfind(ctx, ticker)).unwrap() { - None => sepolia_coin_from_privkey(ctx, priv_key, ticker, conf), + None => sepolia_coin_from_privkey(ctx, priv_key, ticker, conf, erc20), Some(mm_coin) => match mm_coin { MmCoinEnum::EthCoin(coin) => coin, _ => panic!("Unexpected coin type found. Expected MmCoinEnum::EthCoin"), @@ -1578,6 +1588,7 @@ struct SwapAddresses { fallback_swap_contract_address: Address, } +#[allow(dead_code)] impl SwapAddresses { fn init() -> Self { Self { @@ -1592,6 +1603,7 @@ impl SwapAddresses { } } +#[allow(dead_code)] fn eth_coin_v2_activation_with_random_privkey( ticker: &str, conf: &Json, @@ -1639,11 +1651,13 @@ fn eth_coin_v2_activation_with_random_privkey( coin } +#[ignore] #[test] fn send_and_refund_taker_funding_by_secret_eth() { + // sepolia test thread::sleep(Duration::from_secs(1)); - let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf()); - let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf()); + let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); + let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); let taker_secret = vec![0; 32]; let taker_secret_hash = sha256(&taker_secret).to_vec(); @@ -1701,18 +1715,25 @@ fn send_and_refund_taker_funding_by_secret_eth() { #[test] fn send_and_refund_taker_funding_by_secret_erc20() { - let erc20_conf = &erc20_dev_conf(&erc20_contract_checksum()); - let taker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init(), true); - let maker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init(), true); + // TODO move to sepolia + let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); + let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); + let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); let taker_secret = vec![0; 32]; let taker_secret_hash = sha256(&taker_secret).to_vec(); let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); + + let taker_address = block_on(taker_coin.my_addr()); + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + let funding_time_lock = now_sec() + 3000; let payment_time_lock = now_sec() + 1000; - let dex_fee = &DexFee::Standard("0.1".into()); + let dex_fee = &DexFee::Standard("0.00001".into()); + let trading_amount = BigDecimal::from_str("0.0001").unwrap(); + let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); let payment_args = SendTakerFundingArgs { funding_time_lock, @@ -1722,7 +1743,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { maker_pub: maker_pub.as_bytes(), dex_fee, premium_amount: BigDecimal::default(), - trading_amount: 1.into(), + trading_amount: trading_amount.clone(), swap_unique_data: &[], }; @@ -1741,10 +1762,11 @@ fn send_and_refund_taker_funding_by_secret_erc20() { maker_secret_hash: &maker_secret_hash, dex_fee, premium_amount: Default::default(), - trading_amount: 1.into(), + trading_amount, swap_unique_data: &[], watcher_reward: false, }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx_refund = block_on(taker_coin.refund_taker_funding_secret(refund_args)).unwrap(); log!( "Taker refunded ERC20 funding by secret, tx hash: {:02x}", @@ -1753,10 +1775,12 @@ fn send_and_refund_taker_funding_by_secret_erc20() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } +#[ignore] #[test] fn send_and_refund_taker_funding_timelock_eth() { - let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf()); - let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf()); + // sepolia test + let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); + let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); let taker_secret = vec![0; 32]; let taker_secret_hash = sha256(&taker_secret).to_vec(); @@ -1817,24 +1841,29 @@ fn send_and_refund_taker_funding_timelock_eth() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } -#[ignore] #[test] -fn send_and_refund_taker_funding_timelock_erc20() { - let erc20_conf = &erc20_dev_conf(&erc20_contract_checksum()); - let taker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init(), true); - let maker_coin = eth_coin_v2_activation_with_random_privkey(ERC20, erc20_conf, SwapAddresses::init(), true); +fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { + // TODO move to sepolia + let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); + let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); + let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); let taker_secret = vec![0; 32]; let taker_secret_hash = sha256(&taker_secret).to_vec(); let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); + let taker_address = block_on(taker_coin.my_addr()); + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + // if TakerPaymentState is `PaymentSent` then timestamp should exceed payment pre-approve lock time (funding_time_lock) let funding_time_lock = now_sec() + 29; // TODO need to impl taker approve to test exceeded payment_time_lock let payment_time_lock = now_sec() + 1000; - let dex_fee = &DexFee::Standard("0.1".into()); + let dex_fee = &DexFee::Standard("0.00001".into()); + let trading_amount = BigDecimal::from_str("0.0001").unwrap(); + let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); let payment_args = SendTakerFundingArgs { funding_time_lock, @@ -1844,7 +1873,7 @@ fn send_and_refund_taker_funding_timelock_erc20() { maker_pub: maker_pub.as_bytes(), dex_fee, premium_amount: BigDecimal::default(), - trading_amount: 1.into(), + trading_amount: trading_amount.clone(), swap_unique_data: &[], }; let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); @@ -1867,8 +1896,9 @@ fn send_and_refund_taker_funding_timelock_erc20() { watcher_reward: false, dex_fee, premium_amount: BigDecimal::default(), - trading_amount: 1.into(), + trading_amount, }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx_refund = block_on(taker_coin.refund_taker_funding_timelock(refund_args)).unwrap(); log!( "Taker refunded ERC20 funding after pre-approval lock time was exceeded, tx hash: {:02x}", diff --git a/mm2src/mm2_test_helpers/src/for_tests.rs b/mm2src/mm2_test_helpers/src/for_tests.rs index b2f0b537c7..11537c3fb4 100644 --- a/mm2src/mm2_test_helpers/src/for_tests.rs +++ b/mm2src/mm2_test_helpers/src/for_tests.rs @@ -828,6 +828,25 @@ pub fn erc20_dev_conf(contract_address: &str) -> Json { }) } +/// ERC20 token configuration used for dockerized tests on Sepolia +pub fn seploia_erc20_dev_conf(contract_address: &str) -> Json { + json!({ + "coin": "ERC20DEV", + "name": "erc20dev", + "chain_id": 11155111, + "mm2": 1, + "derivation_path": "m/44'/60'", + "protocol": { + "type": "ERC20", + "protocol_data": { + "platform": "ETH", + "contract_address": contract_address, + } + }, + "max_eth_tx_type": 2 + }) +} + /// global NFT configuration used for dockerized Geth dev node pub fn nft_dev_conf() -> Json { json!({ From 84b8ad4c6ad0e9684617856d8c2c4714c65889f3 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 28 Jul 2024 19:39:43 +0700 Subject: [PATCH 143/233] eth tpu v2: validate_taker_funding_impl WIP, provide validation in v2 refund tests. Update nft_maker_swap_v2_bytes and taker_swap_v2_bytes according to the commit link. --- mm2src/coins/coin_errors.rs | 3 +- mm2src/coins/eth.rs | 2 +- mm2src/coins/eth/eth_swap_v2.rs | 149 +++++++++++++++++- mm2src/coins/eth/nft_swap_v2/errors.rs | 14 -- mm2src/coins/eth/nft_swap_v2/mod.rs | 63 +++----- mm2src/coins/eth/nft_swap_v2/structs.rs | 15 -- mm2src/coins/lp_coins.rs | 15 ++ .../tests/docker_tests/docker_tests_common.rs | 2 +- .../tests/docker_tests/eth_docker_tests.rs | 23 ++- .../contract_bytes/nft_maker_swap_v2_bytes | 2 +- .../contract_bytes/taker_swap_v2_bytes | 2 +- 11 files changed, 204 insertions(+), 86 deletions(-) diff --git a/mm2src/coins/coin_errors.rs b/mm2src/coins/coin_errors.rs index 34b0c46486..d6e1015e7e 100644 --- a/mm2src/coins/coin_errors.rs +++ b/mm2src/coins/coin_errors.rs @@ -1,4 +1,5 @@ -use crate::eth::nft_swap_v2::errors::{Erc721FunctionError, HtlcParamsError, PaymentStatusErr, PrepareTxDataError}; +use crate::eth::eth_swap_v2::PaymentStatusErr; +use crate::eth::nft_swap_v2::errors::{Erc721FunctionError, HtlcParamsError, PrepareTxDataError}; use crate::eth::{EthAssocTypesError, EthNftAssocTypesError, Web3RpcError}; use crate::{utxo::rpc_clients::UtxoRpcError, NumConversError, UnexpectedDerivationMethod}; use enum_derives::EnumFromStringify; diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 91761d84e8..8387fa5777 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -158,7 +158,7 @@ mod eip1559_gas_fee; pub(crate) use eip1559_gas_fee::FeePerGasEstimated; use eip1559_gas_fee::{BlocknativeGasApiCaller, FeePerGasSimpleEstimator, GasApiConfig, GasApiProvider, InfuraGasApiCaller}; -mod eth_swap_v2; +pub(crate) mod eth_swap_v2; /// https://github.com/artemii235/etomic-swap/blob/master/contracts/EtomicSwap.sol /// Dev chain (195.201.137.5:8565) contract address: 0x83965C539899cC0F918552e5A26915de40ee8852 diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index f0c2b51207..fd5d3bf284 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,13 +1,18 @@ use super::eth::{wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; use super::{RefundFundingSecretArgs, RefundTakerPaymentArgs, SendTakerFundingArgs, SwapTxTypeWithSecretHash, - Transaction, TransactionErr, ValidateSwapV2TxResult, ValidateTakerFundingArgs}; + TakerPaymentStateV2, Transaction, TransactionErr, ValidateSwapV2TxResult, ValidateTakerFundingArgs}; +use crate::{ParseCoinAssocTypes, ValidateSwapV2TxError}; use enum_derives::EnumFromStringify; -use ethabi::Token; +use ethabi::{Contract, Token}; use ethcore_transaction::Action; use ethereum_types::{Address, Public, U256}; use ethkey::public_to_address; use futures::compat::Future01CompatExt; +use mm2_err_handle::map_to_mm::MapToMmResult; +use mm2_err_handle::mm_error::MmError; +use mm2_number::BigDecimal; use std::convert::TryInto; +use std::num::TryFromIntError; struct TakerFundingArgs { dex_fee: U256, @@ -140,9 +145,57 @@ impl EthCoin { pub(crate) async fn validate_taker_funding_impl( &self, - _args: ValidateTakerFundingArgs<'_, Self>, + args: ValidateTakerFundingArgs<'_, Self>, ) -> ValidateSwapV2TxResult { - todo!() + if let EthCoinType::Nft { .. } = self.coin_type { + return MmError::err(ValidateSwapV2TxError::Internal( + "EthCoinType must be ETH or ERC20".to_string(), + )); + } + let taker_swap_v2_contract = self + .swap_v2_contracts + .as_ref() + .map(|contracts| contracts.taker_swap_v2_contract) + .ok_or_else(|| { + ValidateSwapV2TxError::Internal("Expected swap_v2_contracts to be Some, but found None".to_string()) + })?; + validate_payment_args( + args.taker_secret_hash, + args.maker_secret_hash, + &args.premium_amount, + &args.trading_amount, + ) + .map_err(ValidateSwapV2TxError::Internal)?; + + let _taker_address = public_to_address(args.taker_pub); + let _funding_time_lock: u32 = args + .funding_time_lock + .try_into() + .map_to_mm(|e: TryFromIntError| ValidateSwapV2TxError::LocktimeOverflow(e.to_string()))?; + let payment_time_lock: u32 = args + .payment_time_lock + .try_into() + .map_to_mm(|e: TryFromIntError| ValidateSwapV2TxError::LocktimeOverflow(e.to_string()))?; + let swap_id = self.etomic_swap_id(payment_time_lock, args.maker_secret_hash); + let taker_status = self + .payment_status_v2( + taker_swap_v2_contract, + Token::FixedBytes(swap_id.clone()), + &TAKER_SWAP_V2, + EthPaymentType::TakerPayments, + 3, + ) + .await?; + + // TODO move it to future validate_from_to_and_status function + if taker_status != U256::from(TakerPaymentStateV2::PaymentSent as u8) { + return MmError::err(ValidateSwapV2TxError::UnexpectedPaymentState(format!( + "Taker Payment state is not PaymentSent, got {}", + taker_status + ))); + } + // TODO complete validation + Ok(()) } pub(crate) async fn refund_taker_funding_timelock_impl( @@ -376,6 +429,38 @@ impl EthCoin { ])?; Ok(data) } + + /// Retrieves the payment status from a given smart contract address based on the swap ID and state type. + pub(crate) async fn payment_status_v2( + &self, + swap_address: Address, + swap_id: Token, + contract_abi: &Contract, + state_type: EthPaymentType, + state_index: usize, + ) -> Result { + let function_name = state_type.as_str(); + let function = contract_abi.function(function_name)?; + let data = function.encode_input(&[swap_id])?; + let bytes = self + .call_request(self.my_addr().await, swap_address, None, Some(data.into())) + .await?; + let decoded_tokens = function.decode_output(&bytes.0)?; + + let state = decoded_tokens.get(state_index).ok_or_else(|| { + PaymentStatusErr::Internal(ERRL!( + "Payment status must contain 'state' as the {} token", + state_index + )) + })?; + match state { + Token::Uint(state) => Ok(*state), + _ => Err(PaymentStatusErr::Internal(ERRL!( + "Payment status must be Uint, got {:?}", + state + ))), + } + } } #[derive(Debug, Display, EnumFromStringify)] @@ -387,3 +472,59 @@ enum PrepareTxDataError { #[display(fmt = "Internal error: {}", _0)] Internal(String), } + +fn validate_payment_args<'a>( + taker_secret_hash: &'a [u8], + maker_secret_hash: &'a [u8], + premium_amount: &BigDecimal, + trading_amount: &BigDecimal, +) -> Result<(), String> { + if !is_positive_integer(premium_amount) { + return Err("premium_amount must be a positive integer".to_string()); + } + if !is_positive_integer(trading_amount) { + return Err("trading_amount must be a positive integer".to_string()); + } + if taker_secret_hash.len() != 32 { + return Err("taker_secret_hash must be 32 bytes".to_string()); + } + if maker_secret_hash.len() != 32 { + return Err("maker_secret_hash must be 32 bytes".to_string()); + } + Ok(()) +} + +/// function to check if BigDecimal is a positive integer +#[inline(always)] +pub(crate) fn is_positive_integer(amount: &BigDecimal) -> bool { + amount == &amount.with_scale(0) && amount > &BigDecimal::from(0) +} + +#[allow(dead_code)] +pub(crate) enum EthPaymentType { + MakerPayments, + TakerPayments, +} + +impl EthPaymentType { + pub(crate) fn as_str(&self) -> &'static str { + match self { + EthPaymentType::MakerPayments => "makerPayments", + EthPaymentType::TakerPayments => "takerPayments", + } + } +} + +#[derive(Debug, Display, EnumFromStringify)] +pub(crate) enum PaymentStatusErr { + #[from_stringify("ethabi::Error")] + #[display(fmt = "Abi error: {}", _0)] + AbiError(String), + #[from_stringify("web3::Error")] + #[display(fmt = "Transport error: {}", _0)] + Transport(String), + #[display(fmt = "Internal error: {}", _0)] + Internal(String), + #[display(fmt = "Tx deserialization error: {}", _0)] + TxDeserializationError(String), +} diff --git a/mm2src/coins/eth/nft_swap_v2/errors.rs b/mm2src/coins/eth/nft_swap_v2/errors.rs index e66cd437d0..61d61d731f 100644 --- a/mm2src/coins/eth/nft_swap_v2/errors.rs +++ b/mm2src/coins/eth/nft_swap_v2/errors.rs @@ -12,20 +12,6 @@ pub(crate) enum HtlcParamsError { TxDeserializationError(String), } -#[derive(Debug, Display, EnumFromStringify)] -pub(crate) enum PaymentStatusErr { - #[from_stringify("ethabi::Error")] - #[display(fmt = "Abi error: {}", _0)] - AbiError(String), - #[from_stringify("web3::Error")] - #[display(fmt = "Transport error: {}", _0)] - Transport(String), - #[display(fmt = "Internal error: {}", _0)] - Internal(String), - #[display(fmt = "Tx deserialization error: {}", _0)] - TxDeserializationError(String), -} - #[derive(Debug, Display, EnumFromStringify)] pub(crate) enum PrepareTxDataError { #[from_stringify("ethabi::Error")] diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index 52bff94978..4cf2ad185f 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -10,11 +10,12 @@ use std::convert::TryInto; use web3::types::{Transaction as Web3Tx, TransactionId}; pub(crate) mod errors; -use errors::{Erc721FunctionError, HtlcParamsError, PaymentStatusErr, PrepareTxDataError}; +use errors::{Erc721FunctionError, HtlcParamsError, PrepareTxDataError}; mod structs; -use structs::{ExpectedHtlcParams, PaymentType, ValidationParams}; +use structs::{ExpectedHtlcParams, ValidationParams}; use super::ContractType; +use crate::eth::eth_swap_v2::{is_positive_integer, EthPaymentType, PaymentStatusErr}; use crate::eth::{decode_contract_call, EthCoin, EthCoinType, MakerPaymentStateV2, SignedEthTx, ERC1155_CONTRACT, ERC721_CONTRACT, NFT_MAKER_SWAP_V2}; use crate::{ParseCoinAssocTypes, RefundNftMakerPaymentArgs, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, @@ -65,6 +66,7 @@ impl EthCoin { contract_type, ) .map_err(ValidatePaymentError::InternalError)?; + // TODO use swap contract address from self let etomic_swap_contract = args.nft_swap_info.swap_contract_address; let token_address = args.nft_swap_info.token_address; let maker_address = public_to_address(args.maker_pub); @@ -78,7 +80,8 @@ impl EthCoin { *etomic_swap_contract, Token::FixedBytes(swap_id.clone()), &NFT_MAKER_SWAP_V2, - PaymentType::MakerPayments, + EthPaymentType::MakerPayments, + 2, ) .await?; let tx_from_rpc = self @@ -149,7 +152,8 @@ impl EthCoin { &NFT_MAKER_SWAP_V2, &decoded, bytes_index, - PaymentType::MakerPayments, + EthPaymentType::MakerPayments, + 2 ) .await ); @@ -187,7 +191,8 @@ impl EthCoin { &NFT_MAKER_SWAP_V2, &decoded, bytes_index, - PaymentType::MakerPayments, + EthPaymentType::MakerPayments, + 2 ) .await ); @@ -226,7 +231,8 @@ impl EthCoin { &NFT_MAKER_SWAP_V2, &decoded, bytes_index, - PaymentType::MakerPayments, + EthPaymentType::MakerPayments, + 2 ) .await ); @@ -298,34 +304,6 @@ impl EthCoin { Ok(encoded) } - /// Retrieves the payment status from a given smart contract address based on the swap ID and state type. - async fn payment_status_v2( - &self, - swap_address: Address, - swap_id: Token, - contract_abi: &Contract, - state_type: PaymentType, - ) -> Result { - let function_name = state_type.as_str(); - let function = contract_abi.function(function_name)?; - let data = function.encode_input(&[swap_id])?; - let bytes = self - .call_request(self.my_addr().await, swap_address, None, Some(data.into())) - .await?; - let decoded_tokens = function.decode_output(&bytes.0)?; - - let state = decoded_tokens - .get(2) - .ok_or_else(|| PaymentStatusErr::Internal(ERRL!("Payment status must contain 'state' as the 2nd token")))?; - match state { - Token::Uint(state) => Ok(*state), - _ => Err(PaymentStatusErr::Internal(ERRL!( - "Payment status must be Uint, got {:?}", - state - ))), - } - } - /// Prepares the encoded transaction data for spending a maker's NFT payment on the blockchain. /// /// This function selects the appropriate contract function based on the NFT's contract type (ERC1155 or ERC721) @@ -428,7 +406,8 @@ impl EthCoin { contract_abi: &Contract, decoded_data: &[Token], index: usize, - state_type: PaymentType, + state_type: EthPaymentType, + state_index: usize, ) -> Result<(U256, Vec), PaymentStatusErr> { let data_bytes = match decoded_data.get(index) { Some(Token::Bytes(data_bytes)) => data_bytes, @@ -449,7 +428,13 @@ impl EthCoin { }; let state = self - .payment_status_v2(swap_address, htlc_params[0].clone(), contract_abi, state_type) + .payment_status_v2( + swap_address, + htlc_params[0].clone(), + contract_abi, + state_type, + state_index, + ) .await?; Ok((state, htlc_params)) @@ -555,10 +540,6 @@ fn htlc_params() -> &'static [ethabi::ParamType] { ] } -/// function to check if BigDecimal is a positive integer -#[inline(always)] -fn is_positive_integer(amount: &BigDecimal) -> bool { amount == &amount.with_scale(0) && amount > &BigDecimal::from(0) } - fn validate_payment_args<'a>( taker_secret_hash: &'a [u8], maker_secret_hash: &'a [u8], @@ -595,7 +576,7 @@ async fn validate_from_to_and_maker_status( ) -> ValidatePaymentResult<()> { if maker_status != U256::from(MakerPaymentStateV2::PaymentSent as u8) { return MmError::err(ValidatePaymentError::UnexpectedPaymentState(format!( - "NFT Maker Payment state is not PAYMENT_STATE_SENT, got {}", + "NFT Maker Payment state is not PaymentSent, got {}", maker_status ))); } diff --git a/mm2src/coins/eth/nft_swap_v2/structs.rs b/mm2src/coins/eth/nft_swap_v2/structs.rs index a0c129bf4b..2866d81a01 100644 --- a/mm2src/coins/eth/nft_swap_v2/structs.rs +++ b/mm2src/coins/eth/nft_swap_v2/structs.rs @@ -16,18 +16,3 @@ pub(crate) struct ValidationParams<'a> { // Optional, as it's not needed for ERC721 pub(crate) amount: Option, } - -#[allow(dead_code)] -pub(crate) enum PaymentType { - MakerPayments, - TakerPayments, -} - -impl PaymentType { - pub(crate) fn as_str(&self) -> &'static str { - match self { - PaymentType::MakerPayments => "makerPayments", - PaymentType::TakerPayments => "takerPayments", - } - } -} diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 860aaa4e99..faaa95c757 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -240,6 +240,7 @@ use coin_errors::{MyAddressError, ValidatePaymentError, ValidatePaymentFut, Vali pub mod coins_tests; pub mod eth; +use eth::eth_swap_v2::PaymentStatusErr; use eth::GetValidEthWithdrawAddError; use eth::{eth_coin_from_conf_and_request, get_eth_address, EthCoin, EthGasDetailsErr, EthTxFeeDetails, GetEthAddressError, SignedEthTx}; @@ -1469,6 +1470,8 @@ pub enum ValidateSwapV2TxError { LocktimeOverflow(String), /// Internal error Internal(String), + /// Payment transaction is in unexpected state. E.g., `Uninitialized` instead of `PaymentSent` for ETH payment. + UnexpectedPaymentState(String), } impl From for ValidateSwapV2TxError { @@ -1479,6 +1482,18 @@ impl From for ValidateSwapV2TxError { fn from(err: UtxoRpcError) -> Self { ValidateSwapV2TxError::Rpc(err.to_string()) } } +impl From for ValidateSwapV2TxError { + fn from(err: PaymentStatusErr) -> Self { + match err { + PaymentStatusErr::AbiError(e) + | PaymentStatusErr::Internal(e) + | PaymentStatusErr::TxDeserializationError(e) => ValidateSwapV2TxError::Internal(e), + + PaymentStatusErr::Transport(e) => ValidateSwapV2TxError::Rpc(e), + } + } +} + /// Enum covering error cases that can happen during taker funding spend preimage validation. #[derive(Debug, Display, EnumFromStringify)] pub enum ValidateTakerFundingSpendPreimageError { diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 18c97ad3d8..cfa02420d7 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -145,7 +145,7 @@ pub const ERC1155_TEST_TOKEN_BYTES: &str = include_str!("../../../mm2_test_helpers/contract_bytes/erc1155_test_token_bytes"); pub const NFT_SWAP_CONTRACT_BYTES: &str = include_str!("../../../mm2_test_helpers/contract_bytes/nft_swap_contract_bytes"); -/// https://github.com/KomodoPlatform/etomic-swap/blob/006e6fd52334530f23624a2139d0eb5299c4cd10/contracts/EtomicSwapMakerNftV2Test.sol +/// https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapMakerNftV2.sol pub const NFT_MAKER_SWAP_V2_BYTES: &str = include_str!("../../../mm2_test_helpers/contract_bytes/nft_maker_swap_v2_bytes"); /// https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapMakerNftV2.sol diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 923cd729c1..f1c1344ffc 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -18,7 +18,7 @@ use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, C RefundFundingSecretArgs, RefundNftMakerPaymentArgs, RefundPaymentArgs, RefundTakerPaymentArgs, SearchForSwapTxSpendInput, SendNftMakerPaymentArgs, SendPaymentArgs, SendTakerFundingArgs, SpendNftMakerPaymentArgs, SpendPaymentArgs, SwapOps, SwapTxFeePolicy, SwapTxTypeWithSecretHash, - TakerCoinSwapOpsV2, ToBytes, Transaction, ValidateNftMakerPaymentArgs}; + TakerCoinSwapOpsV2, ToBytes, Transaction, ValidateNftMakerPaymentArgs, ValidateTakerFundingArgs}; use common::{block_on, now_sec}; use crypto::Secp256k1Secret; use ethcore_transaction::Action; @@ -1076,7 +1076,6 @@ fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option Date: Sun, 28 Jul 2024 19:48:31 +0700 Subject: [PATCH 144/233] eth tpu v2 tests: wait pending txs before validation call --- .../tests/docker_tests/eth_docker_tests.rs | 57 ++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index f1c1344ffc..a3cbff80d3 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1664,6 +1664,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { let payment_time_lock = now_sec() + 1000; let taker_address = block_on(taker_coin.my_addr()); + let maker_address = block_on(maker_coin.my_addr()); wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let dex_fee = &DexFee::Standard("0.00001".into()); @@ -1686,19 +1687,20 @@ fn send_and_refund_taker_funding_by_secret_eth() { wait_for_confirmations(&taker_coin, &funding_tx, 100); + let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); let validate = ValidateTakerFundingArgs { funding_tx: &funding_tx, funding_time_lock, payment_time_lock, taker_secret_hash: &taker_secret_hash, maker_secret_hash: &maker_secret_hash, - taker_pub: &(), + taker_pub, dex_fee, premium_amount: Default::default(), trading_amount: trading_amount.clone(), swap_unique_data: &[], }; - + wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); block_on(maker_coin.validate_taker_funding(validate)).unwrap(); let refund_args = RefundFundingSecretArgs { @@ -1737,6 +1739,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { let maker_secret_hash = sha256(&maker_secret).to_vec(); let taker_address = block_on(taker_coin.my_addr()); + let maker_address = block_on(maker_coin.my_addr()); wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_time_lock = now_sec() + 3000; @@ -1763,6 +1766,22 @@ fn send_and_refund_taker_funding_by_secret_erc20() { wait_for_confirmations(&taker_coin, &funding_tx, 100); + let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); + let validate = ValidateTakerFundingArgs { + funding_tx: &funding_tx, + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + taker_pub, + dex_fee, + premium_amount: Default::default(), + trading_amount: trading_amount.clone(), + swap_unique_data: &[], + }; + wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); + block_on(maker_coin.validate_taker_funding(validate)).unwrap(); + let refund_args = RefundFundingSecretArgs { funding_tx: &funding_tx, funding_time_lock, @@ -1798,6 +1817,7 @@ fn send_and_refund_taker_funding_timelock_eth() { let maker_secret_hash = sha256(&maker_secret).to_vec(); let taker_address = block_on(taker_coin.my_addr()); + let maker_address = block_on(maker_coin.my_addr()); wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); // if TakerPaymentState is `PaymentSent` then timestamp should exceed payment pre-approve lock time (funding_time_lock) @@ -1825,6 +1845,22 @@ fn send_and_refund_taker_funding_timelock_eth() { wait_for_confirmations(&taker_coin, &funding_tx, 100); + let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); + let validate = ValidateTakerFundingArgs { + funding_tx: &funding_tx, + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + taker_pub, + dex_fee, + premium_amount: Default::default(), + trading_amount: trading_amount.clone(), + swap_unique_data: &[], + }; + wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); + block_on(maker_coin.validate_taker_funding(validate)).unwrap(); + let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash: &maker_secret_hash, taker_secret_hash: &taker_secret_hash, @@ -1863,6 +1899,7 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { let maker_secret_hash = sha256(&maker_secret).to_vec(); let taker_address = block_on(taker_coin.my_addr()); + let maker_address = block_on(maker_coin.my_addr()); wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); // if TakerPaymentState is `PaymentSent` then timestamp should exceed payment pre-approve lock time (funding_time_lock) @@ -1891,6 +1928,22 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { wait_for_confirmations(&taker_coin, &funding_tx, 100); thread::sleep(Duration::from_secs(30)); + let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); + let validate = ValidateTakerFundingArgs { + funding_tx: &funding_tx, + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + taker_pub, + dex_fee, + premium_amount: Default::default(), + trading_amount: trading_amount.clone(), + swap_unique_data: &[], + }; + wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); + block_on(maker_coin.validate_taker_funding(validate)).unwrap(); + let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash: &maker_secret_hash, taker_secret_hash: &taker_secret_hash, From 10c6a1436f40e4bd7c6baa1ebcadbcf0746413e2 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 28 Jul 2024 20:20:46 +0700 Subject: [PATCH 145/233] eth tpu v2: remove premium from validate_payment_args --- mm2src/coins/eth/eth_swap_v2.rs | 14 +++----------- .../tests/docker_tests/eth_docker_tests.rs | 4 ---- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index fd5d3bf284..b306bf648d 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -159,13 +159,8 @@ impl EthCoin { .ok_or_else(|| { ValidateSwapV2TxError::Internal("Expected swap_v2_contracts to be Some, but found None".to_string()) })?; - validate_payment_args( - args.taker_secret_hash, - args.maker_secret_hash, - &args.premium_amount, - &args.trading_amount, - ) - .map_err(ValidateSwapV2TxError::Internal)?; + validate_payment_args(args.taker_secret_hash, args.maker_secret_hash, &args.trading_amount) + .map_err(ValidateSwapV2TxError::Internal)?; let _taker_address = public_to_address(args.taker_pub); let _funding_time_lock: u32 = args @@ -473,15 +468,12 @@ enum PrepareTxDataError { Internal(String), } +// TODO validate premium when add its support in swap_v2 fn validate_payment_args<'a>( taker_secret_hash: &'a [u8], maker_secret_hash: &'a [u8], - premium_amount: &BigDecimal, trading_amount: &BigDecimal, ) -> Result<(), String> { - if !is_positive_integer(premium_amount) { - return Err("premium_amount must be a positive integer".to_string()); - } if !is_positive_integer(trading_amount) { return Err("trading_amount must be a positive integer".to_string()); } diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index a3cbff80d3..ecd6c2bf62 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1188,7 +1188,6 @@ fn test_nonce_lock() { } } -#[ignore] #[test] fn send_and_refund_erc721_maker_payment_timelock() { thread::sleep(Duration::from_secs(40)); @@ -1231,7 +1230,6 @@ fn send_and_refund_erc721_maker_payment_timelock() { assert_eq!(current_owner, maker_address); } -#[ignore] #[test] fn send_and_refund_erc1155_maker_payment_timelock() { thread::sleep(Duration::from_secs(29)); @@ -1283,7 +1281,6 @@ fn send_and_refund_erc1155_maker_payment_timelock() { assert_eq!(U256::from(amount), balance); } -#[ignore] #[test] fn send_and_refund_erc721_maker_payment_secret() { thread::sleep(Duration::from_secs(5)); @@ -1326,7 +1323,6 @@ fn send_and_refund_erc721_maker_payment_secret() { assert_eq!(current_owner, maker_address); } -#[ignore] #[test] fn send_and_refund_erc1155_maker_payment_secret() { thread::sleep(Duration::from_secs(4)); From d53bc66032720e9d9fb0b36f3bc0ddc1160fd7d2 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 28 Jul 2024 21:03:34 +0700 Subject: [PATCH 146/233] eth tpu v2: use `is_positive` function for eth/erc20 amount --- mm2src/coins/eth/eth_swap_v2.rs | 10 ++++------ mm2src/coins/eth/nft_swap_v2/mod.rs | 6 +++++- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 9 +++++---- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index b306bf648d..1ce1765720 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -474,8 +474,8 @@ fn validate_payment_args<'a>( maker_secret_hash: &'a [u8], trading_amount: &BigDecimal, ) -> Result<(), String> { - if !is_positive_integer(trading_amount) { - return Err("trading_amount must be a positive integer".to_string()); + if !is_positive(trading_amount) { + return Err("trading_amount must be a positive value".to_string()); } if taker_secret_hash.len() != 32 { return Err("taker_secret_hash must be 32 bytes".to_string()); @@ -486,11 +486,9 @@ fn validate_payment_args<'a>( Ok(()) } -/// function to check if BigDecimal is a positive integer +/// function to check if BigDecimal is a positive value #[inline(always)] -pub(crate) fn is_positive_integer(amount: &BigDecimal) -> bool { - amount == &amount.with_scale(0) && amount > &BigDecimal::from(0) -} +fn is_positive(amount: &BigDecimal) -> bool { amount > &BigDecimal::from(0) } #[allow(dead_code)] pub(crate) enum EthPaymentType { diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index 4cf2ad185f..75d3649a5b 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -15,7 +15,7 @@ mod structs; use structs::{ExpectedHtlcParams, ValidationParams}; use super::ContractType; -use crate::eth::eth_swap_v2::{is_positive_integer, EthPaymentType, PaymentStatusErr}; +use crate::eth::eth_swap_v2::{EthPaymentType, PaymentStatusErr}; use crate::eth::{decode_contract_call, EthCoin, EthCoinType, MakerPaymentStateV2, SignedEthTx, ERC1155_CONTRACT, ERC721_CONTRACT, NFT_MAKER_SWAP_V2}; use crate::{ParseCoinAssocTypes, RefundNftMakerPaymentArgs, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, @@ -540,6 +540,10 @@ fn htlc_params() -> &'static [ethabi::ParamType] { ] } +/// function to check if BigDecimal is a positive integer +#[inline(always)] +fn is_positive_integer(amount: &BigDecimal) -> bool { amount == &amount.with_scale(0) && amount > &BigDecimal::from(0) } + fn validate_payment_args<'a>( taker_secret_hash: &'a [u8], maker_secret_hash: &'a [u8], diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index ecd6c2bf62..91e3f3a675 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1661,7 +1661,6 @@ fn send_and_refund_taker_funding_by_secret_eth() { let taker_address = block_on(taker_coin.my_addr()); let maker_address = block_on(maker_coin.my_addr()); - wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let dex_fee = &DexFee::Standard("0.00001".into()); let trading_amount = BigDecimal::from_str("0.0001").unwrap(); @@ -1678,6 +1677,8 @@ fn send_and_refund_taker_funding_by_secret_eth() { trading_amount: trading_amount.clone(), swap_unique_data: &[], }; + + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); @@ -1736,7 +1737,6 @@ fn send_and_refund_taker_funding_by_secret_erc20() { let taker_address = block_on(taker_coin.my_addr()); let maker_address = block_on(maker_coin.my_addr()); - wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_time_lock = now_sec() + 3000; let payment_time_lock = now_sec() + 1000; @@ -1757,6 +1757,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { swap_unique_data: &[], }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); @@ -1814,7 +1815,6 @@ fn send_and_refund_taker_funding_timelock_eth() { let taker_address = block_on(taker_coin.my_addr()); let maker_address = block_on(maker_coin.my_addr()); - wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); // if TakerPaymentState is `PaymentSent` then timestamp should exceed payment pre-approve lock time (funding_time_lock) let funding_time_lock = now_sec() - 3000; @@ -1836,6 +1836,7 @@ fn send_and_refund_taker_funding_timelock_eth() { trading_amount: trading_amount.clone(), swap_unique_data: &[], }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); @@ -1896,7 +1897,6 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { let taker_address = block_on(taker_coin.my_addr()); let maker_address = block_on(maker_coin.my_addr()); - wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); // if TakerPaymentState is `PaymentSent` then timestamp should exceed payment pre-approve lock time (funding_time_lock) let funding_time_lock = now_sec() + 29; @@ -1918,6 +1918,7 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { trading_amount: trading_amount.clone(), swap_unique_data: &[], }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); From 067b2ae4fad9ce9445fd3770cbea90c50f5a02d5 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 28 Jul 2024 21:31:15 +0700 Subject: [PATCH 147/233] eth tpu v2 tests: add sleep Duration --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 91e3f3a675..e9b279c3df 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1648,7 +1648,7 @@ fn eth_coin_v2_activation_with_random_privkey( #[test] fn send_and_refund_taker_funding_by_secret_eth() { // sepolia test - thread::sleep(Duration::from_secs(1)); + thread::sleep(Duration::from_secs(20)); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); @@ -1726,6 +1726,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { #[test] fn send_and_refund_taker_funding_by_secret_erc20() { + thread::sleep(Duration::from_secs(20)); let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); From 9c157e5385d6eb77594f6f2535fe1b42d476c5d4 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 29 Jul 2024 11:25:59 +0700 Subject: [PATCH 148/233] remove dead_code, improve wait_pending_transactions log --- mm2src/coins/eth/eth_swap_v2.rs | 1 - mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 1ce1765720..7dffada691 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -490,7 +490,6 @@ fn validate_payment_args<'a>( #[inline(always)] fn is_positive(amount: &BigDecimal) -> bool { amount > &BigDecimal::from(0) } -#[allow(dead_code)] pub(crate) enum EthPaymentType { MakerPayments, TakerPayments, diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index e9b279c3df..5ac15ca900 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1052,7 +1052,10 @@ fn wait_pending_transactions(wallet_address: Address) { let pending_nonce = block_on(web3.eth().transaction_count(wallet_address, Some(BlockNumber::Pending))).unwrap(); if latest_nonce == pending_nonce { - log!("All pending transactions have been confirmed."); + log!( + "All pending transactions have been confirmed. Latest nonce: {}", + latest_nonce + ); break; } else { log!( @@ -1726,7 +1729,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { #[test] fn send_and_refund_taker_funding_by_secret_erc20() { - thread::sleep(Duration::from_secs(20)); + thread::sleep(Duration::from_secs(30)); let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); From 027da9595d5f954fbc86692d264c045d3ce16e6e Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 29 Jul 2024 11:46:21 +0700 Subject: [PATCH 149/233] change sleep duration --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 5ac15ca900..c78421d3f0 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1729,7 +1729,6 @@ fn send_and_refund_taker_funding_by_secret_eth() { #[test] fn send_and_refund_taker_funding_by_secret_erc20() { - thread::sleep(Duration::from_secs(30)); let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); @@ -1890,6 +1889,7 @@ fn send_and_refund_taker_funding_timelock_eth() { #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { + thread::sleep(Duration::from_secs(30)); let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); From c58808a35d8c9565b067ce9eb10a4dce8b0d205d Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 29 Jul 2024 13:19:20 +0700 Subject: [PATCH 150/233] review: use Public::from_slice directly in parse_pubkey --- mm2src/coins/eth.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index ac79798779..a9a4d77b34 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -6799,8 +6799,6 @@ pub enum EthAssocTypesError { #[from_stringify("DecoderError")] TxParseError(String), ParseSignatureError(String), - #[from_stringify("secp256k1::Error")] - ParsePublicKeyError(String), } #[derive(Debug, Display)] @@ -6843,9 +6841,9 @@ impl ParseCoinAssocTypes for EthCoin { Address::from_str(address).map_to_mm(|e| EthAssocTypesError::InvalidHexString(e.to_string())) } + /// As derive_htlc_pubkey_v2 returns coin specific pubkey we can use [Public::from_slice] directly fn parse_pubkey(&self, pubkey: &[u8]) -> Result { - let pubkey = PublicKey::from_slice(pubkey)?; - Ok(Public::from_slice(&pubkey.serialize_uncompressed()[1..65])) + Ok(Public::from_slice(pubkey)) } fn parse_tx(&self, tx: &[u8]) -> Result { From 1a5bf73a24ddea300411c5b78b7dffa3c8a259da Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 29 Jul 2024 13:22:19 +0700 Subject: [PATCH 151/233] review: use public_to_address to get address from pubkey --- mm2src/coins/eth/eth_swap_v2.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index b5f6a0733e..22dd3c60a7 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,9 +1,10 @@ -use super::eth::{addr_from_raw_pubkey, wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; +use super::eth::{wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; use super::{SendTakerFundingArgs, Transaction, TransactionErr}; use enum_derives::EnumFromStringify; use ethabi::Token; use ethcore_transaction::Action; -use ethereum_types::{Address, U256}; +use ethereum_types::{Address, Public, U256}; +use ethkey::public_to_address; use futures::compat::Future01CompatExt; use std::convert::TryInto; @@ -34,7 +35,7 @@ impl EthCoin { &(args.trading_amount.clone() + args.premium_amount.clone()), self.decimals )); - let maker_address = try_tx_s!(addr_from_raw_pubkey(args.maker_pub)); + let maker_address = public_to_address(&Public::from_slice(args.maker_pub)); let funding_time_lock: u32 = try_tx_s!(args.funding_time_lock.try_into()); let payment_time_lock: u32 = try_tx_s!(args.payment_time_lock.try_into()); From d922395f13e020b47ec6fca4b41ee4d71871a832 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 29 Jul 2024 13:33:10 +0700 Subject: [PATCH 152/233] review: use dex_fee plus payment_amount for eth_total_payment --- mm2src/coins/eth/eth_swap_v2.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 7dffada691..959a895655 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -80,10 +80,7 @@ impl EthCoin { match &self.coin_type { EthCoinType::Eth => { let data = try_tx_s!(self.prepare_taker_eth_funding_data(&funding_args).await); - let eth_total_payment = try_tx_s!(wei_from_big_decimal( - &(args.dex_fee.fee_amount().to_decimal() + args.trading_amount + args.premium_amount), - self.decimals - )); + let eth_total_payment = dex_fee + payment_amount; self.sign_and_send_transaction( eth_total_payment, Action::Call(taker_swap_v2_contract), From 5d6f9437770622c114fe17572254b558f97caddb Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 29 Jul 2024 13:33:10 +0700 Subject: [PATCH 153/233] review: use dex_fee plus payment_amount for eth_total_payment --- mm2src/coins/eth/eth_swap_v2.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 22dd3c60a7..906fafb4df 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -52,10 +52,7 @@ impl EthCoin { match &self.coin_type { EthCoinType::Eth => { let data = try_tx_s!(self.prepare_taker_eth_funding_data(&funding_args).await); - let eth_total_payment = try_tx_s!(wei_from_big_decimal( - &(args.dex_fee.fee_amount().to_decimal() + args.trading_amount + args.premium_amount), - self.decimals - )); + let eth_total_payment = dex_fee + payment_amount; self.sign_and_send_transaction( eth_total_payment, Action::Call(taker_swap_v2_contract), From 2007a703a6d2cd78c974f5b1fa52de78a9ab190d Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 29 Jul 2024 14:19:31 +0700 Subject: [PATCH 154/233] review: extract sign_and_send_transaction outside the if/else --- mm2src/coins/eth/eth_swap_v2.rs | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 906fafb4df..055596bef6 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -85,26 +85,16 @@ impl EthCoin { e )) })?; - self.sign_and_send_transaction( - U256::from(0), - Action::Call(taker_swap_v2_contract), - data, - // TODO need new consts and params for v2 calls. now it uses v1 - U256::from(self.gas_limit.erc20_payment), - ) - .compat() - .await - } else { - self.sign_and_send_transaction( - U256::from(0), - Action::Call(taker_swap_v2_contract), - data, - // TODO need new consts and params for v2 calls. now it uses v1 - U256::from(self.gas_limit.erc20_payment), - ) - .compat() - .await } + self.sign_and_send_transaction( + U256::from(0), + Action::Call(taker_swap_v2_contract), + data, + // TODO need new consts and params for v2 calls. now it uses v1 + U256::from(self.gas_limit.erc20_payment), + ) + .compat() + .await }, EthCoinType::Nft { .. } => Err(TransactionErr::ProtocolNotSupported( "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), From 9aca0d7468b971ff68dbadf487f792360257374c Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 29 Jul 2024 15:37:43 +0700 Subject: [PATCH 155/233] review: minify json --- mm2src/coins/eth/maker_swap_v2_abi.json | 312 +---------------- mm2src/coins/eth/taker_swap_v2_abi.json | 444 +----------------------- 2 files changed, 2 insertions(+), 754 deletions(-) diff --git a/mm2src/coins/eth/maker_swap_v2_abi.json b/mm2src/coins/eth/maker_swap_v2_abi.json index ef34c01910..74e5da3e80 100644 --- a/mm2src/coins/eth/maker_swap_v2_abi.json +++ b/mm2src/coins/eth/maker_swap_v2_abi.json @@ -1,311 +1 @@ -[ - { - "inputs": [ - { - "internalType": "address", - "name": "target", - "type": "address" - } - ], - "name": "AddressEmptyCode", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "AddressInsufficientBalance", - "type": "error" - }, - { - "inputs": [], - "name": "FailedInnerCall", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - } - ], - "name": "SafeERC20FailedOperation", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - } - ], - "name": "MakerPaymentRefundedSecret", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - } - ], - "name": "MakerPaymentRefundedTimelock", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - } - ], - "name": "MakerPaymentSent", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - } - ], - "name": "MakerPaymentSpent", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "address", - "name": "tokenAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "taker", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "takerSecretHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "makerSecretHash", - "type": "bytes32" - }, - { - "internalType": "uint32", - "name": "paymentLockTime", - "type": "uint32" - } - ], - "name": "erc20MakerPayment", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "taker", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "takerSecretHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "makerSecretHash", - "type": "bytes32" - }, - { - "internalType": "uint32", - "name": "paymentLockTime", - "type": "uint32" - } - ], - "name": "ethMakerPayment", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "makerPayments", - "outputs": [ - { - "internalType": "bytes20", - "name": "paymentHash", - "type": "bytes20" - }, - { - "internalType": "uint32", - "name": "paymentLockTime", - "type": "uint32" - }, - { - "internalType": "enum EtomicSwapMakerV2.MakerPaymentState", - "name": "state", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "address", - "name": "taker", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "takerSecret", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "makerSecretHash", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "tokenAddress", - "type": "address" - } - ], - "name": "refundMakerPaymentSecret", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "address", - "name": "taker", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "takerSecretHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "makerSecretHash", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "tokenAddress", - "type": "address" - } - ], - "name": "refundMakerPaymentTimelock", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "address", - "name": "maker", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "takerSecretHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "makerSecret", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "tokenAddress", - "type": "address" - } - ], - "name": "spendMakerPayment", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } -] \ No newline at end of file +[{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"MakerPaymentRefundedSecret","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"MakerPaymentRefundedTimelock","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"MakerPaymentSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"MakerPaymentSpent","type":"event"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"bytes32","name":"takerSecretHash","type":"bytes32"},{"internalType":"bytes32","name":"makerSecretHash","type":"bytes32"},{"internalType":"uint32","name":"paymentLockTime","type":"uint32"}],"name":"erc20MakerPayment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"bytes32","name":"takerSecretHash","type":"bytes32"},{"internalType":"bytes32","name":"makerSecretHash","type":"bytes32"},{"internalType":"uint32","name":"paymentLockTime","type":"uint32"}],"name":"ethMakerPayment","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"makerPayments","outputs":[{"internalType":"bytes20","name":"paymentHash","type":"bytes20"},{"internalType":"uint32","name":"paymentLockTime","type":"uint32"},{"internalType":"enum EtomicSwapMakerV2.MakerPaymentState","name":"state","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"bytes32","name":"takerSecret","type":"bytes32"},{"internalType":"bytes32","name":"makerSecretHash","type":"bytes32"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"refundMakerPaymentSecret","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"bytes32","name":"takerSecretHash","type":"bytes32"},{"internalType":"bytes32","name":"makerSecretHash","type":"bytes32"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"refundMakerPaymentTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"bytes32","name":"takerSecretHash","type":"bytes32"},{"internalType":"bytes32","name":"makerSecret","type":"bytes32"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"spendMakerPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/mm2src/coins/eth/taker_swap_v2_abi.json b/mm2src/coins/eth/taker_swap_v2_abi.json index 9e6b9df006..4f2c8b782c 100644 --- a/mm2src/coins/eth/taker_swap_v2_abi.json +++ b/mm2src/coins/eth/taker_swap_v2_abi.json @@ -1,443 +1 @@ -[ - { - "inputs": [ - { - "internalType": "address", - "name": "feeAddress", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "target", - "type": "address" - } - ], - "name": "AddressEmptyCode", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "AddressInsufficientBalance", - "type": "error" - }, - { - "inputs": [], - "name": "FailedInnerCall", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - } - ], - "name": "SafeERC20FailedOperation", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - } - ], - "name": "TakerPaymentApproved", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "secret", - "type": "bytes32" - } - ], - "name": "TakerPaymentRefundedSecret", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - } - ], - "name": "TakerPaymentRefundedTimelock", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - } - ], - "name": "TakerPaymentSent", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "secret", - "type": "bytes32" - } - ], - "name": "TakerPaymentSpent", - "type": "event" - }, - { - "inputs": [], - "name": "dexFeeAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dexFee", - "type": "uint256" - }, - { - "internalType": "address", - "name": "tokenAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "receiver", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "takerSecretHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "makerSecretHash", - "type": "bytes32" - }, - { - "internalType": "uint32", - "name": "preApproveLockTime", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "paymentLockTime", - "type": "uint32" - } - ], - "name": "erc20TakerPayment", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "dexFee", - "type": "uint256" - }, - { - "internalType": "address", - "name": "receiver", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "takerSecretHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "makerSecretHash", - "type": "bytes32" - }, - { - "internalType": "uint32", - "name": "preApproveLockTime", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "paymentLockTime", - "type": "uint32" - } - ], - "name": "ethTakerPayment", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dexFee", - "type": "uint256" - }, - { - "internalType": "address", - "name": "maker", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "takerSecret", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "makerSecretHash", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "tokenAddress", - "type": "address" - } - ], - "name": "refundTakerPaymentSecret", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dexFee", - "type": "uint256" - }, - { - "internalType": "address", - "name": "maker", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "takerSecretHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "makerSecretHash", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "tokenAddress", - "type": "address" - } - ], - "name": "refundTakerPaymentTimelock", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dexFee", - "type": "uint256" - }, - { - "internalType": "address", - "name": "taker", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "takerSecretHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "makerSecret", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "tokenAddress", - "type": "address" - } - ], - "name": "spendTakerPayment", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dexFee", - "type": "uint256" - }, - { - "internalType": "address", - "name": "maker", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "takerSecretHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "makerSecretHash", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "tokenAddress", - "type": "address" - } - ], - "name": "takerPaymentApprove", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "takerPayments", - "outputs": [ - { - "internalType": "bytes20", - "name": "paymentHash", - "type": "bytes20" - }, - { - "internalType": "uint32", - "name": "preApproveLockTime", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "paymentLockTime", - "type": "uint32" - }, - { - "internalType": "enum EtomicSwapTakerV2.TakerPaymentState", - "name": "state", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - } -] \ No newline at end of file +[{"inputs":[{"internalType":"address","name":"feeAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"TakerPaymentApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"secret","type":"bytes32"}],"name":"TakerPaymentRefundedSecret","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"TakerPaymentRefundedTimelock","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"TakerPaymentSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"secret","type":"bytes32"}],"name":"TakerPaymentSpent","type":"event"},{"inputs":[],"name":"dexFeeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"dexFee","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"takerSecretHash","type":"bytes32"},{"internalType":"bytes32","name":"makerSecretHash","type":"bytes32"},{"internalType":"uint32","name":"preApproveLockTime","type":"uint32"},{"internalType":"uint32","name":"paymentLockTime","type":"uint32"}],"name":"erc20TakerPayment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint256","name":"dexFee","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"takerSecretHash","type":"bytes32"},{"internalType":"bytes32","name":"makerSecretHash","type":"bytes32"},{"internalType":"uint32","name":"preApproveLockTime","type":"uint32"},{"internalType":"uint32","name":"paymentLockTime","type":"uint32"}],"name":"ethTakerPayment","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"dexFee","type":"uint256"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"bytes32","name":"takerSecret","type":"bytes32"},{"internalType":"bytes32","name":"makerSecretHash","type":"bytes32"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"refundTakerPaymentSecret","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"dexFee","type":"uint256"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"bytes32","name":"takerSecretHash","type":"bytes32"},{"internalType":"bytes32","name":"makerSecretHash","type":"bytes32"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"refundTakerPaymentTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"dexFee","type":"uint256"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"bytes32","name":"takerSecretHash","type":"bytes32"},{"internalType":"bytes32","name":"makerSecret","type":"bytes32"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"spendTakerPayment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"dexFee","type":"uint256"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"bytes32","name":"takerSecretHash","type":"bytes32"},{"internalType":"bytes32","name":"makerSecretHash","type":"bytes32"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"takerPaymentApprove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"takerPayments","outputs":[{"internalType":"bytes20","name":"paymentHash","type":"bytes20"},{"internalType":"uint32","name":"preApproveLockTime","type":"uint32"},{"internalType":"uint32","name":"paymentLockTime","type":"uint32"},{"internalType":"enum EtomicSwapTakerV2.TakerPaymentState","name":"state","type":"uint8"}],"stateMutability":"view","type":"function"}] \ No newline at end of file From 2bf52946ae3a8a97df25159184dc213f68da480e Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 29 Jul 2024 18:52:10 +0700 Subject: [PATCH 156/233] eth tpu v2: impl validate_from_to_and_status func, additionally use it in nft swap v2 validation --- mm2src/coins/coin_errors.rs | 11 ++- mm2src/coins/eth/eth_swap_v2.rs | 69 +++++++++++++++---- mm2src/coins/eth/nft_swap_v2/mod.rs | 40 +++-------- mm2src/coins/lp_coins.rs | 18 ++++- .../tests/docker_tests/eth_docker_tests.rs | 2 +- 5 files changed, 91 insertions(+), 49 deletions(-) diff --git a/mm2src/coins/coin_errors.rs b/mm2src/coins/coin_errors.rs index d6e1015e7e..28d4cd41ef 100644 --- a/mm2src/coins/coin_errors.rs +++ b/mm2src/coins/coin_errors.rs @@ -1,4 +1,4 @@ -use crate::eth::eth_swap_v2::PaymentStatusErr; +use crate::eth::eth_swap_v2::{PaymentStatusErr, ValidatePaymentV2Err}; use crate::eth::nft_swap_v2::errors::{Erc721FunctionError, HtlcParamsError, PrepareTxDataError}; use crate::eth::{EthAssocTypesError, EthNftAssocTypesError, Web3RpcError}; use crate::{utxo::rpc_clients::UtxoRpcError, NumConversError, UnexpectedDerivationMethod}; @@ -101,6 +101,15 @@ impl From for ValidatePaymentError { } } +impl From for ValidatePaymentError { + fn from(err: ValidatePaymentV2Err) -> Self { + match err { + ValidatePaymentV2Err::UnexpectedPaymentState(e) => ValidatePaymentError::UnexpectedPaymentState(e), + ValidatePaymentV2Err::WrongPaymentTx(e) => ValidatePaymentError::WrongPaymentTx(e), + } + } +} + #[derive(Debug, Display, EnumFromStringify)] pub enum MyAddressError { #[from_stringify("UnexpectedDerivationMethod")] diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 92772a018a..b57478618c 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,18 +1,18 @@ use super::eth::{wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; -use super::{RefundFundingSecretArgs, RefundTakerPaymentArgs, SendTakerFundingArgs, SwapTxTypeWithSecretHash, - TakerPaymentStateV2, Transaction, TransactionErr, ValidateSwapV2TxResult, ValidateTakerFundingArgs}; -use crate::{ParseCoinAssocTypes, ValidateSwapV2TxError}; +use super::{ParseCoinAssocTypes, RefundFundingSecretArgs, RefundTakerPaymentArgs, SendTakerFundingArgs, + SwapTxTypeWithSecretHash, TakerPaymentStateV2, Transaction, TransactionErr, ValidateSwapV2TxError, + ValidateSwapV2TxResult, ValidateTakerFundingArgs}; use enum_derives::EnumFromStringify; use ethabi::{Contract, Token}; use ethcore_transaction::Action; use ethereum_types::{Address, Public, U256}; use ethkey::public_to_address; use futures::compat::Future01CompatExt; -use mm2_err_handle::map_to_mm::MapToMmResult; -use mm2_err_handle::mm_error::MmError; +use mm2_err_handle::prelude::{MapToMmResult, MmError}; use mm2_number::BigDecimal; use std::convert::TryInto; use std::num::TryFromIntError; +use web3::types::{Transaction as Web3Tx, TransactionId}; struct TakerFundingArgs { dex_fee: U256, @@ -148,8 +148,7 @@ impl EthCoin { })?; validate_payment_args(args.taker_secret_hash, args.maker_secret_hash, &args.trading_amount) .map_err(ValidateSwapV2TxError::Internal)?; - - let _taker_address = public_to_address(args.taker_pub); + let taker_address = public_to_address(args.taker_pub); let _funding_time_lock: u32 = args .funding_time_lock .try_into() @@ -169,13 +168,20 @@ impl EthCoin { ) .await?; - // TODO move it to future validate_from_to_and_status function - if taker_status != U256::from(TakerPaymentStateV2::PaymentSent as u8) { - return MmError::err(ValidateSwapV2TxError::UnexpectedPaymentState(format!( - "Taker Payment state is not PaymentSent, got {}", - taker_status - ))); - } + let tx_from_rpc = self.transaction(TransactionId::Hash(args.funding_tx.tx_hash())).await?; + let tx_from_rpc = tx_from_rpc.as_ref().ok_or_else(|| { + ValidateSwapV2TxError::TxDoesNotExist(format!( + "Didn't find provided tx {:?} on ETH node", + args.funding_tx.tx_hash() + )) + })?; + validate_from_to_and_status( + tx_from_rpc, + taker_address, + taker_swap_v2_contract, + taker_status, + TakerPaymentStateV2::PaymentSent as u8, + )?; // TODO complete validation Ok(()) } @@ -477,6 +483,41 @@ fn validate_payment_args<'a>( #[inline(always)] fn is_positive(amount: &BigDecimal) -> bool { amount > &BigDecimal::from(0) } +pub(crate) fn validate_from_to_and_status( + tx_from_rpc: &Web3Tx, + expected_from: Address, + expected_to: Address, + status: U256, + expected_status: u8, +) -> Result<(), MmError> { + if status != U256::from(expected_status) { + return MmError::err(ValidatePaymentV2Err::UnexpectedPaymentState(format!( + "Payment state is not PaymentSent, got {}", + status + ))); + } + if tx_from_rpc.from != Some(expected_from) { + return MmError::err(ValidatePaymentV2Err::WrongPaymentTx(format!( + "Payment tx {:?} was sent from wrong address, expected {:?}", + tx_from_rpc, expected_from + ))); + } + // (in NFT case) as NFT owner calls "safeTransferFrom" directly, then in Transaction 'to' field we expect token_address + if tx_from_rpc.to != Some(expected_to) { + return MmError::err(ValidatePaymentV2Err::WrongPaymentTx(format!( + "Payment tx {:?} was sent to wrong address, expected {:?}", + tx_from_rpc, expected_to, + ))); + } + Ok(()) +} + +#[derive(Debug, Display)] +pub(crate) enum ValidatePaymentV2Err { + UnexpectedPaymentState(String), + WrongPaymentTx(String), +} + pub(crate) enum EthPaymentType { MakerPayments, TakerPayments, diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index 75d3649a5b..0595bd075c 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -7,7 +7,7 @@ use futures::compat::Future01CompatExt; use mm2_err_handle::prelude::{MapToMmResult, MmError, MmResult}; use mm2_number::BigDecimal; use std::convert::TryInto; -use web3::types::{Transaction as Web3Tx, TransactionId}; +use web3::types::TransactionId; pub(crate) mod errors; use errors::{Erc721FunctionError, HtlcParamsError, PrepareTxDataError}; @@ -15,7 +15,7 @@ mod structs; use structs::{ExpectedHtlcParams, ValidationParams}; use super::ContractType; -use crate::eth::eth_swap_v2::{EthPaymentType, PaymentStatusErr}; +use crate::eth::eth_swap_v2::{validate_from_to_and_status, EthPaymentType, PaymentStatusErr}; use crate::eth::{decode_contract_call, EthCoin, EthCoinType, MakerPaymentStateV2, SignedEthTx, ERC1155_CONTRACT, ERC721_CONTRACT, NFT_MAKER_SWAP_V2}; use crate::{ParseCoinAssocTypes, RefundNftMakerPaymentArgs, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, @@ -93,7 +93,13 @@ impl EthCoin { args.maker_payment_tx.tx_hash() )) })?; - validate_from_to_and_maker_status(tx_from_rpc, maker_address, *token_address, maker_status).await?; + validate_from_to_and_status( + tx_from_rpc, + maker_address, + *token_address, + maker_status, + MakerPaymentStateV2::PaymentSent as u8, + )?; let (decoded, bytes_index) = get_decoded_tx_data_and_bytes_index(contract_type, &tx_from_rpc.input.0)?; @@ -572,34 +578,6 @@ fn validate_payment_args<'a>( Ok(()) } -async fn validate_from_to_and_maker_status( - tx_from_rpc: &Web3Tx, - expected_from: Address, - expected_to: Address, - maker_status: U256, -) -> ValidatePaymentResult<()> { - if maker_status != U256::from(MakerPaymentStateV2::PaymentSent as u8) { - return MmError::err(ValidatePaymentError::UnexpectedPaymentState(format!( - "NFT Maker Payment state is not PaymentSent, got {}", - maker_status - ))); - } - if tx_from_rpc.from != Some(expected_from) { - return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( - "NFT Maker Payment tx {:?} was sent from wrong address, expected {:?}", - tx_from_rpc, expected_from - ))); - } - // As NFT owner calls "safeTransferFrom" directly, then in Transaction 'to' field we expect token_address - if tx_from_rpc.to != Some(expected_to) { - return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( - "NFT Maker Payment tx {:?} was sent to wrong address, expected {:?}", - tx_from_rpc, expected_to, - ))); - } - Ok(()) -} - /// Identifies the correct `"safeTransferFrom"` function based on the contract type (either ERC1155 or ERC721) /// and decodes the provided contract call bytes using the ABI of the identified function. Additionally, it returns /// the index position of the "bytes" field within the function's parameters. diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index faaa95c757..966c6bdddd 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -240,7 +240,7 @@ use coin_errors::{MyAddressError, ValidatePaymentError, ValidatePaymentFut, Vali pub mod coins_tests; pub mod eth; -use eth::eth_swap_v2::PaymentStatusErr; +use eth::eth_swap_v2::{PaymentStatusErr, ValidatePaymentV2Err}; use eth::GetValidEthWithdrawAddError; use eth::{eth_coin_from_conf_and_request, get_eth_address, EthCoin, EthGasDetailsErr, EthTxFeeDetails, GetEthAddressError, SignedEthTx}; @@ -1453,13 +1453,14 @@ impl From for TxGenError { } /// Enum covering error cases that can happen during swap v2 transaction validation. -#[derive(Debug, Display)] +#[derive(Debug, Display, EnumFromStringify)] pub enum ValidateSwapV2TxError { /// Payment sent to wrong address or has invalid amount. InvalidDestinationOrAmount(String), /// Error during conversion of BigDecimal amount to coin's specific monetary units (satoshis, wei, etc.). NumConversion(String), /// RPC error. + #[from_stringify("web3::Error")] Rpc(String), /// Serialized tx bytes don't match ones received from coin's RPC. #[display(fmt = "Tx bytes {:02x} don't match ones received from rpc {:02x}", actual, from_rpc)] @@ -1472,6 +1473,10 @@ pub enum ValidateSwapV2TxError { Internal(String), /// Payment transaction is in unexpected state. E.g., `Uninitialized` instead of `PaymentSent` for ETH payment. UnexpectedPaymentState(String), + /// Payment transaction doesn't exist on-chain. + TxDoesNotExist(String), + /// Transaction has wrong properties, for example, it has been sent to a wrong address. + WrongPaymentTx(String), } impl From for ValidateSwapV2TxError { @@ -1494,6 +1499,15 @@ impl From for ValidateSwapV2TxError { } } +impl From for ValidateSwapV2TxError { + fn from(err: ValidatePaymentV2Err) -> Self { + match err { + ValidatePaymentV2Err::UnexpectedPaymentState(e) => ValidateSwapV2TxError::UnexpectedPaymentState(e), + ValidatePaymentV2Err::WrongPaymentTx(e) => ValidateSwapV2TxError::WrongPaymentTx(e), + } + } +} + /// Enum covering error cases that can happen during taker funding spend preimage validation. #[derive(Debug, Display, EnumFromStringify)] pub enum ValidateTakerFundingSpendPreimageError { diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index c78421d3f0..53b59ce76a 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1889,7 +1889,7 @@ fn send_and_refund_taker_funding_timelock_eth() { #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { - thread::sleep(Duration::from_secs(30)); + thread::sleep(Duration::from_secs(35)); let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); From 8a16714ef2a314ef9ca3385dcaea63a8b1feffec Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 29 Jul 2024 19:40:00 +0700 Subject: [PATCH 157/233] eth tpu v2: change sleep duration in send_and_refund_taker_funding_by_secret_eth --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 53b59ce76a..fcce0e08dd 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1651,7 +1651,7 @@ fn eth_coin_v2_activation_with_random_privkey( #[test] fn send_and_refund_taker_funding_by_secret_eth() { // sepolia test - thread::sleep(Duration::from_secs(20)); + thread::sleep(Duration::from_secs(25)); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); @@ -1682,6 +1682,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { }; wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + thread::sleep(Duration::from_secs(2)); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); From 25074b8234ef82c137c4ac959a1a00da4caf88a4 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 31 Jul 2024 16:32:15 +0700 Subject: [PATCH 158/233] eth tpu v2: validate_taker_funding swap method --- mm2src/coins/eth/eth_swap_v2.rs | 129 +++++++++++++++++-- mm2src/coins/eth/nft_swap_v2/errors.rs | 19 +-- mm2src/coins/lp_coins.rs | 10 ++ mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs | 4 +- mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 4 +- 5 files changed, 139 insertions(+), 27 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index b57478618c..32af296000 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -1,9 +1,9 @@ use super::eth::{wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_SWAP_V2}; -use super::{ParseCoinAssocTypes, RefundFundingSecretArgs, RefundTakerPaymentArgs, SendTakerFundingArgs, - SwapTxTypeWithSecretHash, TakerPaymentStateV2, Transaction, TransactionErr, ValidateSwapV2TxError, - ValidateSwapV2TxResult, ValidateTakerFundingArgs}; +use super::{decode_contract_call, get_function_input_data, ParseCoinAssocTypes, RefundFundingSecretArgs, + RefundTakerPaymentArgs, SendTakerFundingArgs, SwapTxTypeWithSecretHash, TakerPaymentStateV2, Transaction, + TransactionErr, ValidateSwapV2TxError, ValidateSwapV2TxResult, ValidateTakerFundingArgs}; use enum_derives::EnumFromStringify; -use ethabi::{Contract, Token}; +use ethabi::{Contract, Function, Token}; use ethcore_transaction::Action; use ethereum_types::{Address, Public, U256}; use ethkey::public_to_address; @@ -14,6 +14,9 @@ use std::convert::TryInto; use std::num::TryFromIntError; use web3::types::{Transaction as Web3Tx, TransactionId}; +const ETH_TAKER_PAYMENT: &str = "ethTakerPayment"; +const ERC20_TAKER_PAYMENT: &str = "erc20TakerPayment"; + struct TakerFundingArgs { dex_fee: U256, payment_amount: U256, @@ -149,7 +152,7 @@ impl EthCoin { validate_payment_args(args.taker_secret_hash, args.maker_secret_hash, &args.trading_amount) .map_err(ValidateSwapV2TxError::Internal)?; let taker_address = public_to_address(args.taker_pub); - let _funding_time_lock: u32 = args + let funding_time_lock: u32 = args .funding_time_lock .try_into() .map_to_mm(|e: TryFromIntError| ValidateSwapV2TxError::LocktimeOverflow(e.to_string()))?; @@ -182,7 +185,31 @@ impl EthCoin { taker_status, TakerPaymentStateV2::PaymentSent as u8, )?; - // TODO complete validation + let dex_fee = wei_from_big_decimal(&args.dex_fee.fee_amount().into(), self.decimals)?; + let payment_amount = wei_from_big_decimal(&(args.trading_amount + args.premium_amount), self.decimals)?; + let validation_args = TakerValidationArgs { + swap_id, + amount: payment_amount, + dex_fee, + receiver: self.my_addr().await, + taker_secret_hash: args.taker_secret_hash, + maker_secret_hash: args.maker_secret_hash, + funding_time_lock, + payment_time_lock, + }; + match self.coin_type { + EthCoinType::Eth => { + let function = TAKER_SWAP_V2.function(ETH_TAKER_PAYMENT)?; + let decoded = decode_contract_call(function, &tx_from_rpc.input.0)?; + validate_eth_taker_payment_data(&decoded, &validation_args, function, tx_from_rpc.value)?; + }, + EthCoinType::Erc20 { token_addr, .. } => { + let function = TAKER_SWAP_V2.function(ERC20_TAKER_PAYMENT)?; + let decoded = decode_contract_call(function, &tx_from_rpc.input.0)?; + validate_erc20_taker_payment_data(&decoded, &validation_args, function, token_addr)?; + }, + EthCoinType::Nft { .. } => unreachable!(), + } Ok(()) } @@ -203,7 +230,6 @@ impl EthCoin { &(args.trading_amount + args.premium_amount), self.decimals )); - // TODO add maker_pub created by legacy derive_htlc_pubkey support additionally? let maker_address = public_to_address(&Public::from_slice(args.maker_pub)); let payment_time_lock: u32 = try_tx_s!(args.time_lock.try_into()); let (maker_secret_hash, taker_secret_hash) = match args.tx_type_with_secret_hash { @@ -319,7 +345,7 @@ impl EthCoin { /// uint32 preApproveLockTime, /// uint32 paymentLockTime async fn prepare_taker_eth_funding_data(&self, args: &TakerFundingArgs) -> Result, PrepareTxDataError> { - let function = TAKER_SWAP_V2.function("ethTakerPayment")?; + let function = TAKER_SWAP_V2.function(ETH_TAKER_PAYMENT)?; let id = self.etomic_swap_id(args.payment_time_lock, &args.maker_secret_hash); let data = function.encode_input(&[ Token::FixedBytes(id), @@ -349,7 +375,7 @@ impl EthCoin { args: &TakerFundingArgs, token_address: Address, ) -> Result, PrepareTxDataError> { - let function = TAKER_SWAP_V2.function("erc20TakerPayment")?; + let function = TAKER_SWAP_V2.function(ERC20_TAKER_PAYMENT)?; let id = self.etomic_swap_id(args.payment_time_lock, &args.maker_secret_hash); let data = function.encode_input(&[ Token::FixedBytes(id), @@ -452,11 +478,10 @@ impl EthCoin { } #[derive(Debug, Display, EnumFromStringify)] -enum PrepareTxDataError { +pub(crate) enum PrepareTxDataError { #[from_stringify("ethabi::Error")] #[display(fmt = "Abi error: {}", _0)] AbiError(String), - #[allow(dead_code)] #[display(fmt = "Internal error: {}", _0)] Internal(String), } @@ -512,6 +537,88 @@ pub(crate) fn validate_from_to_and_status( Ok(()) } +struct TakerValidationArgs<'a> { + swap_id: Vec, + amount: U256, + dex_fee: U256, + receiver: Address, + taker_secret_hash: &'a [u8], + maker_secret_hash: &'a [u8], + funding_time_lock: u32, + payment_time_lock: u32, +} + +/// Validation function for ETH taker payment data +fn validate_eth_taker_payment_data( + decoded: &[Token], + args: &TakerValidationArgs, + func: &Function, + tx_value: U256, +) -> Result<(), MmError> { + let checks = vec![ + (0, Token::FixedBytes(args.swap_id.clone()), "id"), + (1, Token::Uint(args.dex_fee), "dexFee"), + (2, Token::Address(args.receiver), "receiver"), + (3, Token::FixedBytes(args.taker_secret_hash.to_vec()), "takerSecretHash"), + (4, Token::FixedBytes(args.maker_secret_hash.to_vec()), "makerSecretHash"), + (5, Token::Uint(U256::from(args.funding_time_lock)), "preApproveLockTime"), + (6, Token::Uint(U256::from(args.payment_time_lock)), "paymentLockTime"), + ]; + + for (index, expected_token, field_name) in checks { + let token = get_function_input_data(decoded, func, index).map_to_mm(ValidateSwapV2TxError::Internal)?; + if token != expected_token { + return MmError::err(ValidateSwapV2TxError::WrongPaymentTx(format!( + "ETH Taker Payment `{}` {:?} is invalid, expected {:?}", + field_name, + decoded.get(index), + expected_token + ))); + } + } + let total = args.dex_fee + args.amount; + if total != tx_value { + return MmError::err(ValidateSwapV2TxError::WrongPaymentTx(format!( + "ETH Taker Payment amount, is invalid, expected {:?}, got {:?}", + total, tx_value + ))); + } + Ok(()) +} + +/// Validation function for ERC20 taker payment data +fn validate_erc20_taker_payment_data( + decoded: &[Token], + args: &TakerValidationArgs, + func: &Function, + token_addr: Address, +) -> Result<(), MmError> { + let checks = vec![ + (0, Token::FixedBytes(args.swap_id.clone()), "id"), + (1, Token::Uint(args.amount), "amount"), + (2, Token::Uint(args.dex_fee), "dexFee"), + (3, Token::Address(token_addr), "tokenAddress"), + (4, Token::Address(args.receiver), "receiver"), + (5, Token::FixedBytes(args.taker_secret_hash.to_vec()), "takerSecretHash"), + (6, Token::FixedBytes(args.maker_secret_hash.to_vec()), "makerSecretHash"), + (7, Token::Uint(U256::from(args.funding_time_lock)), "preApproveLockTime"), + (8, Token::Uint(U256::from(args.payment_time_lock)), "paymentLockTime"), + ]; + + for (index, expected_token, field_name) in checks { + let token = get_function_input_data(decoded, func, index).map_to_mm(ValidateSwapV2TxError::Internal)?; + if token != expected_token { + return MmError::err(ValidateSwapV2TxError::WrongPaymentTx(format!( + "ERC20 Taker Payment `{}` {:?} is invalid, expected {:?}", + field_name, + decoded.get(index), + expected_token + ))); + } + } + Ok(()) +} + #[derive(Debug, Display)] pub(crate) enum ValidatePaymentV2Err { UnexpectedPaymentState(String), diff --git a/mm2src/coins/eth/nft_swap_v2/errors.rs b/mm2src/coins/eth/nft_swap_v2/errors.rs index 61d61d731f..3d966cfe02 100644 --- a/mm2src/coins/eth/nft_swap_v2/errors.rs +++ b/mm2src/coins/eth/nft_swap_v2/errors.rs @@ -1,4 +1,4 @@ -use enum_derives::EnumFromStringify; +pub(crate) use crate::eth::eth_swap_v2::PrepareTxDataError; #[derive(Debug, Display)] pub(crate) enum Erc721FunctionError { @@ -12,16 +12,11 @@ pub(crate) enum HtlcParamsError { TxDeserializationError(String), } -#[derive(Debug, Display, EnumFromStringify)] -pub(crate) enum PrepareTxDataError { - #[from_stringify("ethabi::Error")] - #[display(fmt = "Abi error: {}", _0)] - AbiError(String), - #[display(fmt = "Internal error: {}", _0)] - Internal(String), - Erc721FunctionError(Erc721FunctionError), -} - impl From for PrepareTxDataError { - fn from(e: Erc721FunctionError) -> Self { Self::Erc721FunctionError(e) } + fn from(e: Erc721FunctionError) -> Self { + match e { + Erc721FunctionError::AbiError(e) => PrepareTxDataError::AbiError(e), + Erc721FunctionError::FunctionNotFound(e) => PrepareTxDataError::Internal(e), + } + } } diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 966c6bdddd..ca2d23dd08 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -320,6 +320,7 @@ pub mod z_coin; use crate::coin_balance::{BalanceObjectOps, HDWalletBalanceObject}; use z_coin::{ZCoin, ZcoinProtocolInfo}; #[cfg(feature = "enable-sia")] pub mod sia; +use crate::eth::eth_swap_v2::PrepareTxDataError; #[cfg(feature = "enable-sia")] use sia::SiaCoin; pub type TransactionFut = Box + Send>; @@ -1470,6 +1471,7 @@ pub enum ValidateSwapV2TxError { /// Input payment timelock overflows the type used by specific coin. LocktimeOverflow(String), /// Internal error + #[from_stringify("ethabi::Error")] Internal(String), /// Payment transaction is in unexpected state. E.g., `Uninitialized` instead of `PaymentSent` for ETH payment. UnexpectedPaymentState(String), @@ -1508,6 +1510,14 @@ impl From for ValidateSwapV2TxError { } } +impl From for ValidateSwapV2TxError { + fn from(err: PrepareTxDataError) -> Self { + match err { + PrepareTxDataError::AbiError(e) | PrepareTxDataError::Internal(e) => ValidateSwapV2TxError::Internal(e), + } + } +} + /// Enum covering error cases that can happen during taker funding spend preimage validation. #[derive(Debug, Display, EnumFromStringify)] pub enum ValidateTakerFundingSpendPreimageError { diff --git a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs index 753d143f43..de8665ba3e 100644 --- a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs @@ -353,7 +353,7 @@ pub struct MakerSwapStateMachine Date: Thu, 1 Aug 2024 14:56:01 +0700 Subject: [PATCH 159/233] eth tpu v2: prepare_taker_payment_approve_data. remove sleep duration in eth dcoker tests (except seploia) --- mm2src/coins/eth.rs | 10 +- mm2src/coins/eth/eth_swap_v2.rs | 176 ++++++++++++++++-- mm2src/coins/eth/nft_swap_v2/mod.rs | 43 ++--- .../tests/docker_tests/eth_docker_tests.rs | 18 +- 4 files changed, 187 insertions(+), 60 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 5110d84bf2..a05708f509 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7133,10 +7133,10 @@ impl TakerCoinSwapOpsV2 for EthCoin { async fn sign_and_send_taker_funding_spend( &self, _preimage: &TxPreimageWithSig, - _args: &GenTakerFundingSpendArgs<'_, Self>, + args: &GenTakerFundingSpendArgs<'_, Self>, _swap_unique_data: &[u8], ) -> Result { - todo!() + self.taker_payment_approve(args).await } // TODO lets call refund_taker_funding_timelock inside this func? @@ -7173,11 +7173,11 @@ impl TakerCoinSwapOpsV2 for EthCoin { async fn sign_and_broadcast_taker_payment_spend( &self, _preimage: &TxPreimageWithSig, - _gen_args: &GenTakerPaymentSpendArgs<'_, Self>, - _secret: &[u8], + gen_args: &GenTakerPaymentSpendArgs<'_, Self>, + secret: &[u8], _swap_unique_data: &[u8], ) -> Result { - todo!() + self.spend_taker_payment(gen_args, secret).await } async fn wait_for_taker_payment_spend( diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 32af296000..7176afa839 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -2,6 +2,7 @@ use super::eth::{wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_ use super::{decode_contract_call, get_function_input_data, ParseCoinAssocTypes, RefundFundingSecretArgs, RefundTakerPaymentArgs, SendTakerFundingArgs, SwapTxTypeWithSecretHash, TakerPaymentStateV2, Transaction, TransactionErr, ValidateSwapV2TxError, ValidateSwapV2TxResult, ValidateTakerFundingArgs}; +use crate::{GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs}; use enum_derives::EnumFromStringify; use ethabi::{Contract, Function, Token}; use ethcore_transaction::Action; @@ -64,8 +65,6 @@ impl EthCoin { &(args.trading_amount.clone() + args.premium_amount.clone()), self.decimals )); - // TODO add maker_pub created by legacy derive_htlc_pubkey support additionally? - // as derive_htlc_pubkey_v2 function is used for swap_v2, we can call public_to_address let maker_address = public_to_address(&Public::from_slice(args.maker_pub)); let funding_time_lock: u32 = try_tx_s!(args.funding_time_lock.try_into()); @@ -127,9 +126,9 @@ impl EthCoin { .compat() .await }, - EthCoinType::Nft { .. } => Err(TransactionErr::ProtocolNotSupported( - "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), - )), + EthCoinType::Nft { .. } => Err(TransactionErr::ProtocolNotSupported(ERRL!( + "NFT protocol is not supported for ETH and ERC20 Swaps" + ))), } } @@ -213,6 +212,59 @@ impl EthCoin { Ok(()) } + pub(crate) async fn taker_payment_approve( + &self, + args: &GenTakerFundingSpendArgs<'_, Self>, + ) -> Result { + if let EthCoinType::Nft { .. } = self.coin_type { + return Err(TransactionErr::ProtocolNotSupported(ERRL!( + "NFT protocol is not supported for ETH and ERC20 Swaps" + ))); + } + let taker_swap_v2_contract = self + .swap_v2_contracts + .as_ref() + .map(|contracts| contracts.taker_swap_v2_contract) + .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; + + let (send_function, token_address) = match self.coin_type { + EthCoinType::Eth => (try_tx_s!(TAKER_SWAP_V2.function(ETH_TAKER_PAYMENT)), Address::default()), + EthCoinType::Erc20 { token_addr, .. } => { + (try_tx_s!(TAKER_SWAP_V2.function(ERC20_TAKER_PAYMENT)), token_addr) + }, + EthCoinType::Nft { .. } => { + return Err(TransactionErr::ProtocolNotSupported(ERRL!( + "NFT protocol is not supported for ETH and ERC20 Swaps" + ))) + }, + }; + let (state, decoded) = try_tx_s!( + self.status_and_decoded_from_tx_data( + taker_swap_v2_contract, + &TAKER_SWAP_V2, + send_function, + args.funding_tx.unsigned().data(), + EthPaymentType::TakerPayments, + 3 + ) + .await + ); + let data = try_tx_s!( + self.prepare_taker_payment_approve_data(args, decoded, state, token_address) + .await + ); + self.sign_and_send_transaction( + 0.into(), + Action::Call(taker_swap_v2_contract), + data, + // TODO need new consts and params for v2 calls + U256::from(self.gas_limit.eth_max_trade_gas), + ) + .compat() + .await?; + Ok(args.funding_tx.clone()) + } + pub(crate) async fn refund_taker_funding_timelock_impl( &self, args: RefundTakerPaymentArgs<'_>, @@ -253,9 +305,9 @@ impl EthCoin { // TODO need new consts and params for v2 calls. now it uses v1 } => (*token_addr, self.gas_limit.erc20_sender_refund), EthCoinType::Nft { .. } => { - return Err(TransactionErr::ProtocolNotSupported( - "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), - )) + return Err(TransactionErr::ProtocolNotSupported(ERRL!( + "NFT protocol is not supported for ETH and ERC20 Swaps" + ))) }, }; let args = TakerRefundArgs { @@ -309,9 +361,9 @@ impl EthCoin { // TODO need new consts and params for v2 calls. now it uses v1 } => (*token_addr, self.gas_limit.erc20_sender_refund), EthCoinType::Nft { .. } => { - return Err(TransactionErr::ProtocolNotSupported( - "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), - )) + return Err(TransactionErr::ProtocolNotSupported(ERRL!( + "NFT protocol is not supported for ETH and ERC20 Swaps" + ))) }, }; let refund_args = TakerRefundSecretArgs { @@ -335,6 +387,14 @@ impl EthCoin { .await } + pub(crate) async fn spend_taker_payment( + &self, + _gen_args: &GenTakerPaymentSpendArgs<'_, Self>, + _secret: &[u8], + ) -> Result { + todo!() + } + /// Prepares data for EtomicSwapTakerV2 contract `ethTakerPayment` method /// function ethTakerPayment( /// bytes32 id, @@ -444,16 +504,66 @@ impl EthCoin { Ok(data) } + /// This function constructs the encoded transaction input data required to approve the taker payment. + /// The `decoded` parameter should contain the transaction input data from the `ethTakerPayment` or `erc20TakerPayment` function of the EtomicSwapTakerV2 contract. + async fn prepare_taker_payment_approve_data( + &self, + args: &GenTakerFundingSpendArgs<'_, Self>, + decoded: Vec, + state: U256, + token_address: Address, + ) -> Result, PrepareTxDataError> { + validate_payment_state(args.funding_tx, state, TakerPaymentStateV2::PaymentSent as u8)?; + let encoded = match self.coin_type { + EthCoinType::Eth => { + let dex_fee = match &decoded[1] { + Token::Uint(value) => value, + _ => return Err(PrepareTxDataError::Internal("Invalid token type for dex fee".into())), + }; + let amount = args + .funding_tx + .unsigned() + .value() + .checked_sub(*dex_fee) + .ok_or_else(|| { + PrepareTxDataError::Internal("Underflow occurred while calculating amount".into()) + })?; + ethabi::encode(&[ + decoded[0].clone(), // id from ethTakerPayment + Token::Uint(amount), // calculated payment amount (tx value - dexFee) + decoded[1].clone(), // dexFee from ethTakerPayment + decoded[2].clone(), // receiver from ethTakerPayment + Token::FixedBytes(args.taker_secret_hash.to_vec()), + Token::FixedBytes(args.maker_secret_hash.to_vec()), + Token::Address(token_address), // should be zero address Address::default() + ]) + }, + EthCoinType::Erc20 { .. } => ethabi::encode(&[ + decoded[0].clone(), // id from erc20TakerPayment + decoded[1].clone(), // amount from erc20TakerPayment + decoded[2].clone(), // dexFee from erc20TakerPayment + decoded[4].clone(), // receiver from erc20TakerPayment + Token::FixedBytes(args.taker_secret_hash.to_vec()), + Token::FixedBytes(args.maker_secret_hash.to_vec()), + Token::Address(token_address), // erc20 token address from EthCoinType::Erc20 + ]), + EthCoinType::Nft { .. } => { + return Err(PrepareTxDataError::Internal("EthCoinType must be ETH or ERC20".into())) + }, + }; + Ok(encoded) + } + /// Retrieves the payment status from a given smart contract address based on the swap ID and state type. pub(crate) async fn payment_status_v2( &self, swap_address: Address, swap_id: Token, contract_abi: &Contract, - state_type: EthPaymentType, + payment_type: EthPaymentType, state_index: usize, ) -> Result { - let function_name = state_type.as_str(); + let function_name = payment_type.as_str(); let function = contract_abi.function(function_name)?; let data = function.encode_input(&[swap_id])?; let bytes = self @@ -475,6 +585,30 @@ impl EthCoin { ))), } } + + /// Returns payment status and decoded tx input from bytes of contract call + async fn status_and_decoded_from_tx_data( + &self, + swap_address: Address, + contract_abi: &Contract, + func: &Function, + contract_call_bytes: &[u8], + payment_type: EthPaymentType, + state_index: usize, + ) -> Result<(U256, Vec), PaymentStatusErr> { + let decoded = decode_contract_call(func, contract_call_bytes)?; + let state = self + .payment_status_v2( + swap_address, + // swap_id has 0 index + decoded[0].clone(), + contract_abi, + payment_type, + state_index, + ) + .await?; + Ok((state, decoded)) + } } #[derive(Debug, Display, EnumFromStringify)] @@ -619,6 +753,22 @@ fn validate_erc20_taker_payment_data( Ok(()) } +pub(crate) fn validate_payment_state( + tx: &SignedEthTx, + state: U256, + expected_state: u8, +) -> Result<(), PrepareTxDataError> { + if state != U256::from(expected_state) { + return Err(PrepareTxDataError::Internal(ERRL!( + "Payment {:?} state is not {}, got {}", + tx, + expected_state, + state + ))); + } + Ok(()) +} + #[derive(Debug, Display)] pub(crate) enum ValidatePaymentV2Err { UnexpectedPaymentState(String), diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index 0595bd075c..ada63462b1 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -15,7 +15,7 @@ mod structs; use structs::{ExpectedHtlcParams, ValidationParams}; use super::ContractType; -use crate::eth::eth_swap_v2::{validate_from_to_and_status, EthPaymentType, PaymentStatusErr}; +use crate::eth::eth_swap_v2::{validate_from_to_and_status, validate_payment_state, EthPaymentType, PaymentStatusErr}; use crate::eth::{decode_contract_call, EthCoin, EthCoinType, MakerPaymentStateV2, SignedEthTx, ERC1155_CONTRACT, ERC721_CONTRACT, NFT_MAKER_SWAP_V2}; use crate::{ParseCoinAssocTypes, RefundNftMakerPaymentArgs, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, @@ -46,9 +46,9 @@ impl EthCoin { .compat() .await }, - EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported( - "ETH and ERC20 Protocols are not supported for NFT Swaps".to_string(), - )), + EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported(ERRL!( + "ETH and ERC20 Protocols are not supported for NFT Swaps" + ))), } } @@ -173,9 +173,9 @@ impl EthCoin { .compat() .await }, - EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported( - "ETH and ERC20 Protocols are not supported for NFT Swaps".to_string(), - )), + EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported(ERRL!( + "ETH and ERC20 Protocols are not supported for NFT Swaps" + ))), } } @@ -213,9 +213,9 @@ impl EthCoin { .compat() .await }, - EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported( - "ETH and ERC20 Protocols are not supported for NFT Swaps".to_string(), - )), + EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported(ERRL!( + "ETH and ERC20 Protocols are not supported for NFT Swaps" + ))), } } @@ -254,9 +254,9 @@ impl EthCoin { .compat() .await }, - EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported( - "ETH and ERC20 Protocols are not supported for NFT Swaps".to_string(), - )), + EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported(ERRL!( + "ETH and ERC20 Protocols are not supported for NFT Swaps" + ))), } } @@ -412,7 +412,7 @@ impl EthCoin { contract_abi: &Contract, decoded_data: &[Token], index: usize, - state_type: EthPaymentType, + payment_type: EthPaymentType, state_index: usize, ) -> Result<(U256, Vec), PaymentStatusErr> { let data_bytes = match decoded_data.get(index) { @@ -436,9 +436,10 @@ impl EthCoin { let state = self .payment_status_v2( swap_address, + // swap_id has 0 index htlc_params[0].clone(), contract_abi, - state_type, + payment_type, state_index, ) .await?; @@ -619,15 +620,3 @@ fn erc721_transfer_with_data<'a>() -> Result<&'a ethabi::Function, Erc721Functio })?; Ok(function) } - -fn validate_payment_state(tx: &SignedEthTx, state: U256, expected_state: u8) -> Result<(), PrepareTxDataError> { - if state != U256::from(expected_state) { - return Err(PrepareTxDataError::Internal(ERRL!( - "Payment {:?} state is not {}, got {}", - tx, - expected_state, - state - ))); - } - Ok(()) -} diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index fcce0e08dd..98241d9019 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -696,7 +696,6 @@ pub fn fill_eth_erc20_with_private_key(priv_key: Secp256k1Secret) { } fn send_and_refund_eth_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { - thread::sleep(Duration::from_secs(3)); let eth_coin = eth_coin_with_random_privkey(swap_contract()); eth_coin.set_swap_transaction_fee_policy(swap_txfee_policy); @@ -770,13 +769,11 @@ fn send_and_refund_eth_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { assert_eq!(expected, search_tx); } -#[ignore] #[test] fn send_and_refund_eth_maker_payment_internal_gas_policy() { send_and_refund_eth_maker_payment_impl(SwapTxFeePolicy::Internal); } -#[ignore] #[test] fn send_and_refund_eth_maker_payment_priority_fee() { send_and_refund_eth_maker_payment_impl(SwapTxFeePolicy::Medium); } @@ -857,18 +854,15 @@ fn send_and_spend_eth_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { assert_eq!(expected, search_tx); } -#[ignore] #[test] fn send_and_spend_eth_maker_payment_internal_gas_policy() { send_and_spend_eth_maker_payment_impl(SwapTxFeePolicy::Internal); } -#[ignore] #[test] fn send_and_spend_eth_maker_payment_priority_fee() { send_and_spend_eth_maker_payment_impl(SwapTxFeePolicy::Medium); } fn send_and_refund_erc20_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { - thread::sleep(Duration::from_secs(10)); let erc20_coin = erc20_coin_with_random_privkey(swap_contract()); erc20_coin.set_swap_transaction_fee_policy(swap_txfee_policy); @@ -954,7 +948,6 @@ fn send_and_refund_erc20_maker_payment_priority_fee() { } fn send_and_spend_erc20_maker_payment_impl(swap_txfee_policy: SwapTxFeePolicy) { - thread::sleep(Duration::from_secs(5)); let maker_erc20_coin = erc20_coin_with_random_privkey(swap_contract()); let taker_erc20_coin = erc20_coin_with_random_privkey(swap_contract()); @@ -1081,7 +1074,6 @@ fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option Date: Thu, 1 Aug 2024 18:46:57 +0700 Subject: [PATCH 160/233] eth tpu v2: spend payment functionality, send_approve_and_spend_eth test --- mm2src/coins/eth.rs | 4 +- mm2src/coins/eth/eth_swap_v2.rs | 132 +++++++++++++++--- .../tests/docker_tests/eth_docker_tests.rs | 117 +++++++++++++++- 3 files changed, 227 insertions(+), 26 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index a05708f509..c2b73aa3d3 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7129,7 +7129,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { Ok(()) } - /// takerPaymentApprove is called here for EVM based chains + /// Taker approves payment calling `takerPaymentApprove` here for EVM based chains async fn sign_and_send_taker_funding_spend( &self, _preimage: &TxPreimageWithSig, @@ -7177,7 +7177,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { secret: &[u8], _swap_unique_data: &[u8], ) -> Result { - self.spend_taker_payment(gen_args, secret).await + self.sign_and_broadcast_taker_payment_spend_impl(gen_args, secret).await } async fn wait_for_taker_payment_spend( diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 7176afa839..aece15c28e 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -238,19 +238,9 @@ impl EthCoin { ))) }, }; - let (state, decoded) = try_tx_s!( - self.status_and_decoded_from_tx_data( - taker_swap_v2_contract, - &TAKER_SWAP_V2, - send_function, - args.funding_tx.unsigned().data(), - EthPaymentType::TakerPayments, - 3 - ) - .await - ); + let decoded = try_tx_s!(decode_contract_call(send_function, args.funding_tx.unsigned().data())); let data = try_tx_s!( - self.prepare_taker_payment_approve_data(args, decoded, state, token_address) + self.prepare_taker_payment_approve_data(args, decoded, token_address) .await ); self.sign_and_send_transaction( @@ -387,12 +377,76 @@ impl EthCoin { .await } - pub(crate) async fn spend_taker_payment( + pub(crate) async fn sign_and_broadcast_taker_payment_spend_impl( &self, - _gen_args: &GenTakerPaymentSpendArgs<'_, Self>, - _secret: &[u8], + gen_args: &GenTakerPaymentSpendArgs<'_, Self>, + secret: &[u8], ) -> Result { - todo!() + if let EthCoinType::Nft { .. } = self.coin_type { + return Err(TransactionErr::ProtocolNotSupported(ERRL!( + "NFT protocol is not supported for ETH and ERC20 Swaps" + ))); + } + let taker_swap_v2_contract = self + .swap_v2_contracts + .as_ref() + .map(|contracts| contracts.taker_swap_v2_contract) + .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; + + let (send_function, token_address) = match self.coin_type { + EthCoinType::Eth => (try_tx_s!(TAKER_SWAP_V2.function(ETH_TAKER_PAYMENT)), Address::default()), + EthCoinType::Erc20 { token_addr, .. } => { + (try_tx_s!(TAKER_SWAP_V2.function(ERC20_TAKER_PAYMENT)), token_addr) + }, + EthCoinType::Nft { .. } => { + return Err(TransactionErr::ProtocolNotSupported(ERRL!( + "NFT protocol is not supported for ETH and ERC20 Swaps" + ))) + }, + }; + let (state, decoded) = try_tx_s!( + self.status_and_decoded_from_tx_data( + taker_swap_v2_contract, + &TAKER_SWAP_V2, + send_function, + gen_args.taker_tx.unsigned().data(), + EthPaymentType::TakerPayments, + 3 + ) + .await + ); + let data = try_tx_s!( + self.prepare_spend_taker_payment_data(gen_args, secret, decoded, state, token_address) + .await + ); + let payment_tx = match self.coin_type { + EthCoinType::Eth => { + self.sign_and_send_transaction( + 0.into(), + Action::Call(taker_swap_v2_contract), + data, + // TODO need new consts and params for v2 calls + U256::from(self.gas_limit.eth_receiver_spend), + ) + .compat() + .await? + }, + EthCoinType::Erc20 { .. } => { + self.sign_and_send_transaction( + 0.into(), + Action::Call(taker_swap_v2_contract), + data, + // TODO need new consts and params for v2 calls + U256::from(self.gas_limit.erc20_receiver_spend), + ) + .compat() + .await? + }, + EthCoinType::Nft { .. } => { + unreachable!() + }, + }; + Ok(payment_tx) } /// Prepares data for EtomicSwapTakerV2 contract `ethTakerPayment` method @@ -510,10 +564,8 @@ impl EthCoin { &self, args: &GenTakerFundingSpendArgs<'_, Self>, decoded: Vec, - state: U256, token_address: Address, ) -> Result, PrepareTxDataError> { - validate_payment_state(args.funding_tx, state, TakerPaymentStateV2::PaymentSent as u8)?; let encoded = match self.coin_type { EthCoinType::Eth => { let dex_fee = match &decoded[1] { @@ -554,6 +606,50 @@ impl EthCoin { Ok(encoded) } + async fn prepare_spend_taker_payment_data( + &self, + args: &GenTakerPaymentSpendArgs<'_, Self>, + secret: &[u8], + decoded: Vec, + state: U256, + token_address: Address, + ) -> Result, PrepareTxDataError> { + validate_payment_state(args.taker_tx, state, TakerPaymentStateV2::TakerApproved as u8)?; + let encoded = match self.coin_type { + EthCoinType::Eth => { + let dex_fee = match &decoded[1] { + Token::Uint(value) => value, + _ => return Err(PrepareTxDataError::Internal("Invalid token type for dex fee".into())), + }; + let amount = args.taker_tx.unsigned().value().checked_sub(*dex_fee).ok_or_else(|| { + PrepareTxDataError::Internal("Underflow occurred while calculating amount".into()) + })?; + ethabi::encode(&[ + decoded[0].clone(), // id from ethTakerPayment + Token::Uint(amount), // calculated payment amount (tx value - dexFee) + decoded[1].clone(), // dexFee from ethTakerPayment + decoded[2].clone(), // receiver from ethTakerPayment + decoded[3].clone(), // takerSecretHash from ethTakerPayment + Token::FixedBytes(secret.to_vec()), // makerSecret + Token::Address(token_address), // should be zero address Address::default() + ]) + }, + EthCoinType::Erc20 { .. } => ethabi::encode(&[ + decoded[0].clone(), // id from erc20TakerPayment + decoded[1].clone(), // amount from erc20TakerPayment + decoded[2].clone(), // dexFee from erc20TakerPayment + decoded[4].clone(), // receiver from erc20TakerPayment + decoded[5].clone(), // takerSecretHash from erc20TakerPayment + Token::FixedBytes(secret.to_vec()), // makerSecret + Token::Address(token_address), // erc20 token address from EthCoinType::Erc20 + ]), + EthCoinType::Nft { .. } => { + return Err(PrepareTxDataError::Internal("EthCoinType must be ETH or ERC20".into())) + }, + }; + Ok(encoded) + } + /// Retrieves the payment status from a given smart contract address based on the swap ID and state type. pub(crate) async fn payment_status_v2( &self, diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 98241d9019..5ac31f77e4 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -13,12 +13,13 @@ use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_reque EthPrivKeyBuildPolicy, SignedEthTx, SwapV2Contracts, ERC20_ABI}; use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, CommonSwapOpsV2, ConfirmPaymentInput, - DerivationMethod, DexFee, Eip1559Ops, FoundSwapTxSpend, MakerNftSwapOpsV2, MarketCoinOps, MmCoinEnum, - MmCoinStruct, NftSwapInfo, ParseCoinAssocTypes, ParseNftAssocTypes, PrivKeyBuildPolicy, - RefundFundingSecretArgs, RefundNftMakerPaymentArgs, RefundPaymentArgs, RefundTakerPaymentArgs, - SearchForSwapTxSpendInput, SendNftMakerPaymentArgs, SendPaymentArgs, SendTakerFundingArgs, - SpendNftMakerPaymentArgs, SpendPaymentArgs, SwapOps, SwapTxFeePolicy, SwapTxTypeWithSecretHash, - TakerCoinSwapOpsV2, ToBytes, Transaction, ValidateNftMakerPaymentArgs, ValidateTakerFundingArgs}; + DerivationMethod, DexFee, Eip1559Ops, FoundSwapTxSpend, GenTakerFundingSpendArgs, + GenTakerPaymentSpendArgs, MakerNftSwapOpsV2, MarketCoinOps, MmCoinEnum, MmCoinStruct, NftSwapInfo, + ParseCoinAssocTypes, ParseNftAssocTypes, PrivKeyBuildPolicy, RefundFundingSecretArgs, + RefundNftMakerPaymentArgs, RefundPaymentArgs, RefundTakerPaymentArgs, SearchForSwapTxSpendInput, + SendNftMakerPaymentArgs, SendPaymentArgs, SendTakerFundingArgs, SpendNftMakerPaymentArgs, + SpendPaymentArgs, SwapOps, SwapTxFeePolicy, SwapTxTypeWithSecretHash, TakerCoinSwapOpsV2, ToBytes, + Transaction, TxPreimageWithSig, ValidateNftMakerPaymentArgs, ValidateTakerFundingArgs}; use common::{block_on, now_sec}; use crypto::Secp256k1Secret; use ethcore_transaction::Action; @@ -1635,6 +1636,7 @@ fn eth_coin_v2_activation_with_random_privkey( coin } +#[ignore] #[test] fn send_and_refund_taker_funding_by_secret_eth() { // sepolia test @@ -1715,6 +1717,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } +#[ignore] #[test] fn send_and_refund_taker_funding_by_secret_erc20() { let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); @@ -1793,6 +1796,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } +#[ignore] #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { thread::sleep(Duration::from_secs(10)); @@ -1876,6 +1880,107 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } +#[test] +fn send_approve_and_spend_eth() { + // sepolia test + thread::sleep(Duration::from_secs(25)); + let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); + let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); + + let taker_secret = vec![0; 32]; + let taker_secret_hash = sha256(&taker_secret).to_vec(); + let maker_secret = vec![1; 32]; + let maker_secret_hash = sha256(&maker_secret).to_vec(); + let funding_time_lock = now_sec() + 3000; + let payment_time_lock = now_sec() + 1000; + + let taker_address = block_on(taker_coin.my_addr()); + let maker_address = block_on(maker_coin.my_addr()); + + let dex_fee = &DexFee::Standard("0.00001".into()); + let trading_amount = BigDecimal::from_str("0.0001").unwrap(); + + let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); + let payment_args = SendTakerFundingArgs { + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + maker_pub: maker_pub.as_bytes(), + dex_fee, + premium_amount: BigDecimal::default(), + trading_amount: trading_amount.clone(), + swap_unique_data: &[], + }; + + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); + log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); + + wait_for_confirmations(&taker_coin, &funding_tx, 100); + + let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); + let validate = ValidateTakerFundingArgs { + funding_tx: &funding_tx, + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + taker_pub, + dex_fee, + premium_amount: Default::default(), + trading_amount: trading_amount.clone(), + swap_unique_data: &[], + }; + wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); + block_on(maker_coin.validate_taker_funding(validate)).unwrap(); + + let approve_args = GenTakerFundingSpendArgs { + funding_tx: &funding_tx, + maker_pub, + taker_pub, + funding_time_lock, + taker_secret_hash: &taker_secret_hash, + taker_payment_time_lock: funding_time_lock, + maker_secret_hash: &maker_secret_hash, + }; + let preimage = TxPreimageWithSig { + preimage: funding_tx.clone(), + signature: taker_coin.parse_signature(&[0u8; 65]).unwrap(), + }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + let taker_approve_tx = + block_on(taker_coin.sign_and_send_taker_funding_spend(&preimage, &approve_args, &[])).unwrap(); + log!( + "Taker approved ETH payment, tx hash: {:02x}", + taker_approve_tx.tx_hash() + ); + wait_for_confirmations(&taker_coin, &taker_approve_tx, 100); + + let dex_fee_pub = sepolia_taker_swap_v2(); + let spend_args = GenTakerPaymentSpendArgs { + taker_tx: &funding_tx, + time_lock: payment_time_lock, + maker_secret_hash: &maker_secret_hash, + maker_pub, + maker_address: &maker_address, + taker_pub, + dex_fee_pub: dex_fee_pub.as_bytes(), + dex_fee, + premium_amount: Default::default(), + trading_amount, + }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + let spend_tx = + block_on(taker_coin.sign_and_broadcast_taker_payment_spend(&preimage, &spend_args, &maker_secret, &[])) + .unwrap(); + log!("Maker spent ETH payment, tx hash: {:02x}", taker_approve_tx.tx_hash()); + wait_for_confirmations(&maker_coin, &spend_tx, 100); + + // TODO add wait_for_taker_payment_spend when it will be implemented +} + +#[ignore] #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { thread::sleep(Duration::from_secs(40)); From 4ef88fafa54cd954a258fd27235206dc882fa94a Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 1 Aug 2024 19:46:22 +0700 Subject: [PATCH 161/233] eth tpu v2: log approve tx --- mm2src/coins/eth.rs | 4 ++-- mm2src/coins/eth/eth_swap_v2.rs | 3 ++- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index c2b73aa3d3..2142639e9f 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7129,7 +7129,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { Ok(()) } - /// Taker approves payment calling `takerPaymentApprove` here for EVM based chains + /// Taker approves payment calling `takerPaymentApprove` for EVM based chains async fn sign_and_send_taker_funding_spend( &self, _preimage: &TxPreimageWithSig, @@ -7169,7 +7169,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { Ok(()) } - /// spendTakerPayment is called here for EVM based chains + /// Taker swap contract `spendTakerPayment` method is called for EVM based chains async fn sign_and_broadcast_taker_payment_spend( &self, _preimage: &TxPreimageWithSig, diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index aece15c28e..292b88e50c 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -243,7 +243,7 @@ impl EthCoin { self.prepare_taker_payment_approve_data(args, decoded, token_address) .await ); - self.sign_and_send_transaction( + let tx = self.sign_and_send_transaction( 0.into(), Action::Call(taker_swap_v2_contract), data, @@ -252,6 +252,7 @@ impl EthCoin { ) .compat() .await?; + log!("approve tx: {:?}", tx); Ok(args.funding_tx.clone()) } diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 5ac31f77e4..047d220bbf 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1974,7 +1974,7 @@ fn send_approve_and_spend_eth() { let spend_tx = block_on(taker_coin.sign_and_broadcast_taker_payment_spend(&preimage, &spend_args, &maker_secret, &[])) .unwrap(); - log!("Maker spent ETH payment, tx hash: {:02x}", taker_approve_tx.tx_hash()); + log!("Maker spent ETH payment, tx hash: {:02x}", spend_tx.tx_hash()); wait_for_confirmations(&maker_coin, &spend_tx, 100); // TODO add wait_for_taker_payment_spend when it will be implemented From fac2d3865aa96b570618a0035668da727595326d Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 1 Aug 2024 20:20:03 +0700 Subject: [PATCH 162/233] eth tpu v2: refactor spend functionality --- mm2src/coins/eth/eth_swap_v2.rs | 85 ++++++------------- .../tests/docker_tests/eth_docker_tests.rs | 7 +- 2 files changed, 31 insertions(+), 61 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 292b88e50c..0572c5f5a5 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -243,17 +243,19 @@ impl EthCoin { self.prepare_taker_payment_approve_data(args, decoded, token_address) .await ); - let tx = self.sign_and_send_transaction( - 0.into(), - Action::Call(taker_swap_v2_contract), - data, - // TODO need new consts and params for v2 calls - U256::from(self.gas_limit.eth_max_trade_gas), - ) - .compat() - .await?; - log!("approve tx: {:?}", tx); - Ok(args.funding_tx.clone()) + let approve_tx = self + .sign_and_send_transaction( + 0.into(), + Action::Call(taker_swap_v2_contract), + data, + // TODO need new consts and params for v2 calls + U256::from(self.gas_limit.eth_max_trade_gas), + ) + .compat() + .await?; + log!("approve tx: {:?}", approve_tx); + log!("approve tx hash: {:02x}", approve_tx.tx_hash()); + Ok(approve_tx) } pub(crate) async fn refund_taker_funding_timelock_impl( @@ -393,23 +395,13 @@ impl EthCoin { .as_ref() .map(|contracts| contracts.taker_swap_v2_contract) .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; - - let (send_function, token_address) = match self.coin_type { - EthCoinType::Eth => (try_tx_s!(TAKER_SWAP_V2.function(ETH_TAKER_PAYMENT)), Address::default()), - EthCoinType::Erc20 { token_addr, .. } => { - (try_tx_s!(TAKER_SWAP_V2.function(ERC20_TAKER_PAYMENT)), token_addr) - }, - EthCoinType::Nft { .. } => { - return Err(TransactionErr::ProtocolNotSupported(ERRL!( - "NFT protocol is not supported for ETH and ERC20 Swaps" - ))) - }, - }; + let approve_func = try_tx_s!(TAKER_SWAP_V2.function("takerPaymentApprove")); let (state, decoded) = try_tx_s!( self.status_and_decoded_from_tx_data( taker_swap_v2_contract, &TAKER_SWAP_V2, - send_function, + approve_func, + // taker_tx should be approved tx gen_args.taker_tx.unsigned().data(), EthPaymentType::TakerPayments, 3 @@ -417,7 +409,7 @@ impl EthCoin { .await ); let data = try_tx_s!( - self.prepare_spend_taker_payment_data(gen_args, secret, decoded, state, token_address) + self.prepare_spend_taker_payment_data(gen_args, secret, decoded, state) .await ); let payment_tx = match self.coin_type { @@ -613,41 +605,18 @@ impl EthCoin { secret: &[u8], decoded: Vec, state: U256, - token_address: Address, ) -> Result, PrepareTxDataError> { validate_payment_state(args.taker_tx, state, TakerPaymentStateV2::TakerApproved as u8)?; - let encoded = match self.coin_type { - EthCoinType::Eth => { - let dex_fee = match &decoded[1] { - Token::Uint(value) => value, - _ => return Err(PrepareTxDataError::Internal("Invalid token type for dex fee".into())), - }; - let amount = args.taker_tx.unsigned().value().checked_sub(*dex_fee).ok_or_else(|| { - PrepareTxDataError::Internal("Underflow occurred while calculating amount".into()) - })?; - ethabi::encode(&[ - decoded[0].clone(), // id from ethTakerPayment - Token::Uint(amount), // calculated payment amount (tx value - dexFee) - decoded[1].clone(), // dexFee from ethTakerPayment - decoded[2].clone(), // receiver from ethTakerPayment - decoded[3].clone(), // takerSecretHash from ethTakerPayment - Token::FixedBytes(secret.to_vec()), // makerSecret - Token::Address(token_address), // should be zero address Address::default() - ]) - }, - EthCoinType::Erc20 { .. } => ethabi::encode(&[ - decoded[0].clone(), // id from erc20TakerPayment - decoded[1].clone(), // amount from erc20TakerPayment - decoded[2].clone(), // dexFee from erc20TakerPayment - decoded[4].clone(), // receiver from erc20TakerPayment - decoded[5].clone(), // takerSecretHash from erc20TakerPayment - Token::FixedBytes(secret.to_vec()), // makerSecret - Token::Address(token_address), // erc20 token address from EthCoinType::Erc20 - ]), - EthCoinType::Nft { .. } => { - return Err(PrepareTxDataError::Internal("EthCoinType must be ETH or ERC20".into())) - }, - }; + let taker_address = public_to_address(args.taker_pub); + let encoded = ethabi::encode(&[ + decoded[0].clone(), // id from takerPaymentApprove + decoded[1].clone(), // amount from takerPaymentApprove + decoded[2].clone(), // dexFee from takerPaymentApprove + Token::Address(taker_address), // taker address + decoded[4].clone(), // takerSecretHash from ethTakerPayment + Token::FixedBytes(secret.to_vec()), // makerSecret + decoded[6].clone(), // tokenAddress from takerPaymentApprove + ]); Ok(encoded) } diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 047d220bbf..38d073013a 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1948,6 +1948,7 @@ fn send_approve_and_spend_eth() { preimage: funding_tx.clone(), signature: taker_coin.parse_signature(&[0u8; 65]).unwrap(), }; + wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let taker_approve_tx = block_on(taker_coin.sign_and_send_taker_funding_spend(&preimage, &approve_args, &[])).unwrap(); @@ -1959,7 +1960,7 @@ fn send_approve_and_spend_eth() { let dex_fee_pub = sepolia_taker_swap_v2(); let spend_args = GenTakerPaymentSpendArgs { - taker_tx: &funding_tx, + taker_tx: &taker_approve_tx, time_lock: payment_time_lock, maker_secret_hash: &maker_secret_hash, maker_pub, @@ -1970,9 +1971,9 @@ fn send_approve_and_spend_eth() { premium_amount: Default::default(), trading_amount, }; - wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); let spend_tx = - block_on(taker_coin.sign_and_broadcast_taker_payment_spend(&preimage, &spend_args, &maker_secret, &[])) + block_on(maker_coin.sign_and_broadcast_taker_payment_spend(&preimage, &spend_args, &maker_secret, &[])) .unwrap(); log!("Maker spent ETH payment, tx hash: {:02x}", spend_tx.tx_hash()); wait_for_confirmations(&maker_coin, &spend_tx, 100); From b2d6d4bed8fe38bbcc3b6c83137d0f4845df11b2 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 1 Aug 2024 21:15:39 +0700 Subject: [PATCH 163/233] eth tpu v2: check payment state in approve --- mm2src/coins/eth/eth_swap_v2.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 0572c5f5a5..d998056e1e 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -238,9 +238,19 @@ impl EthCoin { ))) }, }; - let decoded = try_tx_s!(decode_contract_call(send_function, args.funding_tx.unsigned().data())); + let (state, decoded) = try_tx_s!( + self.status_and_decoded_from_tx_data( + taker_swap_v2_contract, + &TAKER_SWAP_V2, + send_function, + args.funding_tx.unsigned().data(), + EthPaymentType::TakerPayments, + 3 + ) + .await + ); let data = try_tx_s!( - self.prepare_taker_payment_approve_data(args, decoded, token_address) + self.prepare_taker_payment_approve_data(args, decoded, token_address, state) .await ); let approve_tx = self @@ -249,12 +259,10 @@ impl EthCoin { Action::Call(taker_swap_v2_contract), data, // TODO need new consts and params for v2 calls - U256::from(self.gas_limit.eth_max_trade_gas), + U256::from(self.gas_limit.eth_payment), ) .compat() .await?; - log!("approve tx: {:?}", approve_tx); - log!("approve tx hash: {:02x}", approve_tx.tx_hash()); Ok(approve_tx) } @@ -558,7 +566,9 @@ impl EthCoin { args: &GenTakerFundingSpendArgs<'_, Self>, decoded: Vec, token_address: Address, + state: U256, ) -> Result, PrepareTxDataError> { + validate_payment_state(args.funding_tx, state, TakerPaymentStateV2::PaymentSent as u8)?; let encoded = match self.coin_type { EthCoinType::Eth => { let dex_fee = match &decoded[1] { From 70dfcdc00a255de5e294d3a06825e56744cd527e Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 1 Aug 2024 22:04:52 +0700 Subject: [PATCH 164/233] eth tpu v2: use function.encode_input --- mm2src/coins/eth/eth_swap_v2.rs | 36 ++++++++++++--------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index d998056e1e..094ee8439c 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -238,19 +238,9 @@ impl EthCoin { ))) }, }; - let (state, decoded) = try_tx_s!( - self.status_and_decoded_from_tx_data( - taker_swap_v2_contract, - &TAKER_SWAP_V2, - send_function, - args.funding_tx.unsigned().data(), - EthPaymentType::TakerPayments, - 3 - ) - .await - ); + let decoded = try_tx_s!(decode_contract_call(send_function, args.funding_tx.unsigned().data())); let data = try_tx_s!( - self.prepare_taker_payment_approve_data(args, decoded, token_address, state) + self.prepare_taker_payment_approve_data(args, decoded, token_address) .await ); let approve_tx = self @@ -566,10 +556,9 @@ impl EthCoin { args: &GenTakerFundingSpendArgs<'_, Self>, decoded: Vec, token_address: Address, - state: U256, ) -> Result, PrepareTxDataError> { - validate_payment_state(args.funding_tx, state, TakerPaymentStateV2::PaymentSent as u8)?; - let encoded = match self.coin_type { + let function = TAKER_SWAP_V2.function("takerPaymentApprove")?; + let data = match self.coin_type { EthCoinType::Eth => { let dex_fee = match &decoded[1] { Token::Uint(value) => value, @@ -583,7 +572,7 @@ impl EthCoin { .ok_or_else(|| { PrepareTxDataError::Internal("Underflow occurred while calculating amount".into()) })?; - ethabi::encode(&[ + function.encode_input(&[ decoded[0].clone(), // id from ethTakerPayment Token::Uint(amount), // calculated payment amount (tx value - dexFee) decoded[1].clone(), // dexFee from ethTakerPayment @@ -591,9 +580,9 @@ impl EthCoin { Token::FixedBytes(args.taker_secret_hash.to_vec()), Token::FixedBytes(args.maker_secret_hash.to_vec()), Token::Address(token_address), // should be zero address Address::default() - ]) + ])? }, - EthCoinType::Erc20 { .. } => ethabi::encode(&[ + EthCoinType::Erc20 { .. } => function.encode_input(&[ decoded[0].clone(), // id from erc20TakerPayment decoded[1].clone(), // amount from erc20TakerPayment decoded[2].clone(), // dexFee from erc20TakerPayment @@ -601,12 +590,12 @@ impl EthCoin { Token::FixedBytes(args.taker_secret_hash.to_vec()), Token::FixedBytes(args.maker_secret_hash.to_vec()), Token::Address(token_address), // erc20 token address from EthCoinType::Erc20 - ]), + ])?, EthCoinType::Nft { .. } => { return Err(PrepareTxDataError::Internal("EthCoinType must be ETH or ERC20".into())) }, }; - Ok(encoded) + Ok(data) } async fn prepare_spend_taker_payment_data( @@ -617,8 +606,9 @@ impl EthCoin { state: U256, ) -> Result, PrepareTxDataError> { validate_payment_state(args.taker_tx, state, TakerPaymentStateV2::TakerApproved as u8)?; + let function = TAKER_SWAP_V2.function("spendTakerPayment")?; let taker_address = public_to_address(args.taker_pub); - let encoded = ethabi::encode(&[ + let data = function.encode_input(&[ decoded[0].clone(), // id from takerPaymentApprove decoded[1].clone(), // amount from takerPaymentApprove decoded[2].clone(), // dexFee from takerPaymentApprove @@ -626,8 +616,8 @@ impl EthCoin { decoded[4].clone(), // takerSecretHash from ethTakerPayment Token::FixedBytes(secret.to_vec()), // makerSecret decoded[6].clone(), // tokenAddress from takerPaymentApprove - ]); - Ok(encoded) + ])?; + Ok(data) } /// Retrieves the payment status from a given smart contract address based on the swap ID and state type. From fe730faeaf5c1a3ff352947dc64420d9b1b2ed7d Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 2 Aug 2024 09:48:53 +0700 Subject: [PATCH 165/233] review: drop variables, return result value directly --- mm2src/coins/eth.rs | 10 ++++------ mm2src/coins/eth/eth_swap_v2.rs | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index a9a4d77b34..7974e29668 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7108,11 +7108,10 @@ impl TakerCoinSwapOpsV2 for EthCoin { args: &GenTakerFundingSpendArgs<'_, Self>, _swap_unique_data: &[u8], ) -> GenPreimageResult { - let result = TxPreimageWithSig { + Ok(TxPreimageWithSig { preimage: args.funding_tx.clone(), signature: args.funding_tx.signature(), - }; - Ok(result) + }) } /// Eth doesnt have preimages @@ -7144,11 +7143,10 @@ impl TakerCoinSwapOpsV2 for EthCoin { args: &GenTakerPaymentSpendArgs<'_, Self>, _swap_unique_data: &[u8], ) -> GenPreimageResult { - let result = TxPreimageWithSig { + Ok(TxPreimageWithSig { preimage: args.taker_tx.clone(), signature: args.taker_tx.signature(), - }; - Ok(result) + }) } /// Eth doesnt have preimages diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 055596bef6..295fd7af2c 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -35,20 +35,20 @@ impl EthCoin { &(args.trading_amount.clone() + args.premium_amount.clone()), self.decimals )); - let maker_address = public_to_address(&Public::from_slice(args.maker_pub)); - - let funding_time_lock: u32 = try_tx_s!(args.funding_time_lock.try_into()); - let payment_time_lock: u32 = try_tx_s!(args.payment_time_lock.try_into()); - let funding_args = TakerFundingArgs { - dex_fee, - payment_amount, - maker_address, - taker_secret_hash: try_tx_s!(args.taker_secret_hash.try_into()), - maker_secret_hash: try_tx_s!(args.maker_secret_hash.try_into()), - funding_time_lock, - payment_time_lock, + let funding_args = { + let maker_address = public_to_address(&Public::from_slice(args.maker_pub)); + let funding_time_lock: u32 = try_tx_s!(args.funding_time_lock.try_into()); + let payment_time_lock: u32 = try_tx_s!(args.payment_time_lock.try_into()); + TakerFundingArgs { + dex_fee, + payment_amount, + maker_address, + taker_secret_hash: try_tx_s!(args.taker_secret_hash.try_into()), + maker_secret_hash: try_tx_s!(args.maker_secret_hash.try_into()), + funding_time_lock, + payment_time_lock, + } }; - match &self.coin_type { EthCoinType::Eth => { let data = try_tx_s!(self.prepare_taker_eth_funding_data(&funding_args).await); From a814575f7829f39f1580c40c41da75f73501a075 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 2 Aug 2024 15:39:22 +0700 Subject: [PATCH 166/233] eth tpu v2: use match self.coin_type for token_address in sign_and_broadcast_taker_payment_spend_impl --- mm2src/coins/eth/eth_swap_v2.rs | 34 ++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 85a71666e5..be1c90e715 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -216,18 +216,13 @@ impl EthCoin { &self, args: &GenTakerFundingSpendArgs<'_, Self>, ) -> Result { - if let EthCoinType::Nft { .. } = self.coin_type { - return Err(TransactionErr::ProtocolNotSupported(ERRL!( - "NFT protocol is not supported for ETH and ERC20 Swaps" - ))); - } let taker_swap_v2_contract = self .swap_v2_contracts .as_ref() .map(|contracts| contracts.taker_swap_v2_contract) .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; - let (send_function, token_address) = match self.coin_type { + let (send_func, token_address) = match self.coin_type { EthCoinType::Eth => (try_tx_s!(TAKER_SWAP_V2.function(ETH_TAKER_PAYMENT)), Address::default()), EthCoinType::Erc20 { token_addr, .. } => { (try_tx_s!(TAKER_SWAP_V2.function(ERC20_TAKER_PAYMENT)), token_addr) @@ -238,7 +233,7 @@ impl EthCoin { ))) }, }; - let decoded = try_tx_s!(decode_contract_call(send_function, args.funding_tx.unsigned().data())); + let decoded = try_tx_s!(decode_contract_call(send_func, args.funding_tx.unsigned().data())); let data = try_tx_s!( self.prepare_taker_payment_approve_data(args, decoded, token_address) .await @@ -383,17 +378,25 @@ impl EthCoin { gen_args: &GenTakerPaymentSpendArgs<'_, Self>, secret: &[u8], ) -> Result { - if let EthCoinType::Nft { .. } = self.coin_type { - return Err(TransactionErr::ProtocolNotSupported(ERRL!( - "NFT protocol is not supported for ETH and ERC20 Swaps" - ))); - } let taker_swap_v2_contract = self .swap_v2_contracts .as_ref() .map(|contracts| contracts.taker_swap_v2_contract) .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; - let approve_func = try_tx_s!(TAKER_SWAP_V2.function("takerPaymentApprove")); + let (approve_func, token_address) = match self.coin_type { + EthCoinType::Eth => ( + try_tx_s!(TAKER_SWAP_V2.function("takerPaymentApprove")), + Address::default(), + ), + EthCoinType::Erc20 { token_addr, .. } => { + (try_tx_s!(TAKER_SWAP_V2.function("takerPaymentApprove")), token_addr) + }, + EthCoinType::Nft { .. } => { + return Err(TransactionErr::ProtocolNotSupported(ERRL!( + "NFT protocol is not supported for ETH and ERC20 Swaps" + ))) + }, + }; let (state, decoded) = try_tx_s!( self.status_and_decoded_from_tx_data( taker_swap_v2_contract, @@ -407,7 +410,7 @@ impl EthCoin { .await ); let data = try_tx_s!( - self.prepare_spend_taker_payment_data(gen_args, secret, decoded, state) + self.prepare_spend_taker_payment_data(gen_args, secret, decoded, state, token_address) .await ); let payment_tx = match self.coin_type { @@ -604,6 +607,7 @@ impl EthCoin { secret: &[u8], decoded: Vec, state: U256, + token_address: Address, ) -> Result, PrepareTxDataError> { validate_payment_state(args.taker_tx, state, TakerPaymentStateV2::TakerApproved as u8)?; let function = TAKER_SWAP_V2.function("spendTakerPayment")?; @@ -615,7 +619,7 @@ impl EthCoin { Token::Address(taker_address), // taker address decoded[4].clone(), // takerSecretHash from ethTakerPayment Token::FixedBytes(secret.to_vec()), // makerSecret - decoded[6].clone(), // tokenAddress from takerPaymentApprove + Token::Address(token_address), // tokenAddress ])?; Ok(data) } From bd41f9ad3028864ca132d44fe7b4142709a4e18c Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 2 Aug 2024 16:30:24 +0700 Subject: [PATCH 167/233] eth tpu v2 tests: try geth_send_approve_and_spend_eth --- .../tests/docker_tests/eth_docker_tests.rs | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 38d073013a..60fa919d38 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1981,6 +1981,96 @@ fn send_approve_and_spend_eth() { // TODO add wait_for_taker_payment_spend when it will be implemented } +#[test] +fn geth_send_approve_and_spend_eth() { + let taker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init(), false); + let maker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init(), false); + + let taker_secret = vec![0; 32]; + let taker_secret_hash = sha256(&taker_secret).to_vec(); + let maker_secret = vec![1; 32]; + let maker_secret_hash = sha256(&maker_secret).to_vec(); + let funding_time_lock = now_sec() + 3000; + let payment_time_lock = now_sec() + 1000; + + let dex_fee = &DexFee::Standard("0.00001".into()); + let trading_amount = BigDecimal::from_str("0.0001").unwrap(); + + let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); + let payment_args = SendTakerFundingArgs { + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + maker_pub: maker_pub.as_bytes(), + dex_fee, + premium_amount: BigDecimal::default(), + trading_amount: trading_amount.clone(), + swap_unique_data: &[], + }; + let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); + log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); + wait_for_confirmations(&taker_coin, &funding_tx, 100); + + let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); + let validate = ValidateTakerFundingArgs { + funding_tx: &funding_tx, + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + taker_pub, + dex_fee, + premium_amount: Default::default(), + trading_amount: trading_amount.clone(), + swap_unique_data: &[], + }; + block_on(maker_coin.validate_taker_funding(validate)).unwrap(); + + let approve_args = GenTakerFundingSpendArgs { + funding_tx: &funding_tx, + maker_pub, + taker_pub, + funding_time_lock, + taker_secret_hash: &taker_secret_hash, + taker_payment_time_lock: funding_time_lock, + maker_secret_hash: &maker_secret_hash, + }; + let preimage = TxPreimageWithSig { + preimage: funding_tx.clone(), + signature: taker_coin.parse_signature(&[0u8; 65]).unwrap(), + }; + let taker_approve_tx = + block_on(taker_coin.sign_and_send_taker_funding_spend(&preimage, &approve_args, &[])).unwrap(); + log!( + "Taker approved ETH payment, tx hash: {:02x}", + taker_approve_tx.tx_hash() + ); + wait_for_confirmations(&taker_coin, &taker_approve_tx, 100); + + let maker_address = block_on(maker_coin.my_addr()); + let dex_fee_pub = taker_swap_v2(); + let spend_args = GenTakerPaymentSpendArgs { + taker_tx: &taker_approve_tx, + time_lock: payment_time_lock, + maker_secret_hash: &maker_secret_hash, + maker_pub, + maker_address: &maker_address, + taker_pub, + dex_fee_pub: dex_fee_pub.as_bytes(), + dex_fee, + premium_amount: Default::default(), + trading_amount, + }; + let spend_tx = + block_on(maker_coin.sign_and_broadcast_taker_payment_spend(&preimage, &spend_args, &maker_secret, &[])) + .unwrap(); + log!("Maker spent ETH payment, tx hash: {:02x}", spend_tx.tx_hash()); + wait_for_confirmations(&maker_coin, &spend_tx, 100); + + // TODO add wait_for_taker_payment_spend when it will be implemented +} + #[ignore] #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { From d6e42c505c2f25999c0adadcf322d591442e291c Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 2 Aug 2024 17:23:00 +0700 Subject: [PATCH 168/233] eth tpu v2: refactor spend. approve impls. docker tests: send_approve_and_spend_erc20. --- mm2src/coins/eth/eth_swap_v2.rs | 74 +++++-------- .../tests/docker_tests/eth_docker_tests.rs | 103 ++++++++++++++++++ 2 files changed, 133 insertions(+), 44 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index be1c90e715..3fc2337e5e 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -184,17 +184,20 @@ impl EthCoin { taker_status, TakerPaymentStateV2::PaymentSent as u8, )?; - let dex_fee = wei_from_big_decimal(&args.dex_fee.fee_amount().into(), self.decimals)?; - let payment_amount = wei_from_big_decimal(&(args.trading_amount + args.premium_amount), self.decimals)?; - let validation_args = TakerValidationArgs { - swap_id, - amount: payment_amount, - dex_fee, - receiver: self.my_addr().await, - taker_secret_hash: args.taker_secret_hash, - maker_secret_hash: args.maker_secret_hash, - funding_time_lock, - payment_time_lock, + + let validation_args = { + let dex_fee = wei_from_big_decimal(&args.dex_fee.fee_amount().into(), self.decimals)?; + let payment_amount = wei_from_big_decimal(&(args.trading_amount + args.premium_amount), self.decimals)?; + TakerValidationArgs { + swap_id, + amount: payment_amount, + dex_fee, + receiver: self.my_addr().await, + taker_secret_hash: args.taker_secret_hash, + maker_secret_hash: args.maker_secret_hash, + funding_time_lock, + payment_time_lock, + } }; match self.coin_type { EthCoinType::Eth => { @@ -238,14 +241,14 @@ impl EthCoin { self.prepare_taker_payment_approve_data(args, decoded, token_address) .await ); + // TODO need new consts and params for v2 calls, create provide approve const + let gas_limit = match self.coin_type { + EthCoinType::Eth => U256::from(self.gas_limit.eth_payment), + EthCoinType::Erc20 { .. } => U256::from(self.gas_limit.eth_payment), + EthCoinType::Nft { .. } => unreachable!(), // EthCoinType::Nft case was already checked + }; let approve_tx = self - .sign_and_send_transaction( - 0.into(), - Action::Call(taker_swap_v2_contract), - data, - // TODO need new consts and params for v2 calls - U256::from(self.gas_limit.eth_payment), - ) + .sign_and_send_transaction(0.into(), Action::Call(taker_swap_v2_contract), data, gas_limit) .compat() .await?; Ok(approve_tx) @@ -413,33 +416,16 @@ impl EthCoin { self.prepare_spend_taker_payment_data(gen_args, secret, decoded, state, token_address) .await ); - let payment_tx = match self.coin_type { - EthCoinType::Eth => { - self.sign_and_send_transaction( - 0.into(), - Action::Call(taker_swap_v2_contract), - data, - // TODO need new consts and params for v2 calls - U256::from(self.gas_limit.eth_receiver_spend), - ) - .compat() - .await? - }, - EthCoinType::Erc20 { .. } => { - self.sign_and_send_transaction( - 0.into(), - Action::Call(taker_swap_v2_contract), - data, - // TODO need new consts and params for v2 calls - U256::from(self.gas_limit.erc20_receiver_spend), - ) - .compat() - .await? - }, - EthCoinType::Nft { .. } => { - unreachable!() - }, + // TODO need new consts and params for v2 calls + let gas_limit = match self.coin_type { + EthCoinType::Eth => U256::from(self.gas_limit.eth_receiver_spend), + EthCoinType::Erc20 { .. } => U256::from(self.gas_limit.erc20_receiver_spend), + EthCoinType::Nft { .. } => unreachable!(), // EthCoinType::Nft case was already checked }; + let payment_tx = self + .sign_and_send_transaction(0.into(), Action::Call(taker_swap_v2_contract), data, gas_limit) + .compat() + .await?; Ok(payment_tx) } diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 60fa919d38..57f838394f 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1981,8 +1981,111 @@ fn send_approve_and_spend_eth() { // TODO add wait_for_taker_payment_spend when it will be implemented } +#[test] +fn send_approve_and_spend_erc20() { + // sepolia test + thread::sleep(Duration::from_secs(15)); + let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); + let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, erc20_conf, true); + let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, erc20_conf, true); + + let taker_secret = vec![0; 32]; + let taker_secret_hash = sha256(&taker_secret).to_vec(); + let maker_secret = vec![1; 32]; + let maker_secret_hash = sha256(&maker_secret).to_vec(); + let funding_time_lock = now_sec() + 3000; + let payment_time_lock = now_sec() + 1000; + + let taker_address = block_on(taker_coin.my_addr()); + let maker_address = block_on(maker_coin.my_addr()); + + let dex_fee = &DexFee::Standard("0.00001".into()); + let trading_amount = BigDecimal::from_str("0.0001").unwrap(); + + let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); + let payment_args = SendTakerFundingArgs { + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + maker_pub: maker_pub.as_bytes(), + dex_fee, + premium_amount: BigDecimal::default(), + trading_amount: trading_amount.clone(), + swap_unique_data: &[], + }; + + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); + log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); + + wait_for_confirmations(&taker_coin, &funding_tx, 100); + + let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); + let validate = ValidateTakerFundingArgs { + funding_tx: &funding_tx, + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + taker_pub, + dex_fee, + premium_amount: Default::default(), + trading_amount: trading_amount.clone(), + swap_unique_data: &[], + }; + wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); + block_on(maker_coin.validate_taker_funding(validate)).unwrap(); + + let approve_args = GenTakerFundingSpendArgs { + funding_tx: &funding_tx, + maker_pub, + taker_pub, + funding_time_lock, + taker_secret_hash: &taker_secret_hash, + taker_payment_time_lock: funding_time_lock, + maker_secret_hash: &maker_secret_hash, + }; + let preimage = TxPreimageWithSig { + preimage: funding_tx.clone(), + signature: taker_coin.parse_signature(&[0u8; 65]).unwrap(), + }; + wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + let taker_approve_tx = + block_on(taker_coin.sign_and_send_taker_funding_spend(&preimage, &approve_args, &[])).unwrap(); + log!( + "Taker approved ERC20 payment, tx hash: {:02x}", + taker_approve_tx.tx_hash() + ); + wait_for_confirmations(&taker_coin, &taker_approve_tx, 100); + + let dex_fee_pub = sepolia_taker_swap_v2(); + let spend_args = GenTakerPaymentSpendArgs { + taker_tx: &taker_approve_tx, + time_lock: payment_time_lock, + maker_secret_hash: &maker_secret_hash, + maker_pub, + maker_address: &maker_address, + taker_pub, + dex_fee_pub: dex_fee_pub.as_bytes(), + dex_fee, + premium_amount: Default::default(), + trading_amount, + }; + wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); + let spend_tx = + block_on(maker_coin.sign_and_broadcast_taker_payment_spend(&preimage, &spend_args, &maker_secret, &[])) + .unwrap(); + log!("Maker spent ERC20 payment, tx hash: {:02x}", spend_tx.tx_hash()); + wait_for_confirmations(&maker_coin, &spend_tx, 100); + + // TODO add wait_for_taker_payment_spend when it will be implemented +} + #[test] fn geth_send_approve_and_spend_eth() { + thread::sleep(Duration::from_secs(3)); let taker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init(), false); let maker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init(), false); From 6949b7af818cc5f9ce14bb86c0c334de367703bb Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 4 Aug 2024 21:00:08 +0700 Subject: [PATCH 169/233] eth tpu v2 tests: send_and_refund_taker_funding_exceed_payment_timelock ETH/ERC20 --- .../tests/docker_tests/eth_docker_tests.rs | 215 +++++++++++++++++- 1 file changed, 205 insertions(+), 10 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 57f838394f..01e015ef3e 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1796,7 +1796,6 @@ fn send_and_refund_taker_funding_by_secret_erc20() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } -#[ignore] #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { thread::sleep(Duration::from_secs(10)); @@ -1835,7 +1834,6 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 100); let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); @@ -1912,11 +1910,9 @@ fn send_approve_and_spend_eth() { trading_amount: trading_amount.clone(), swap_unique_data: &[], }; - wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 100); let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); @@ -2014,11 +2010,9 @@ fn send_approve_and_spend_erc20() { trading_amount: trading_amount.clone(), swap_unique_data: &[], }; - wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 100); let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); @@ -2083,6 +2077,7 @@ fn send_approve_and_spend_erc20() { // TODO add wait_for_taker_payment_spend when it will be implemented } +#[ignore] #[test] fn geth_send_approve_and_spend_eth() { thread::sleep(Duration::from_secs(3)); @@ -2096,8 +2091,8 @@ fn geth_send_approve_and_spend_eth() { let funding_time_lock = now_sec() + 3000; let payment_time_lock = now_sec() + 1000; - let dex_fee = &DexFee::Standard("0.00001".into()); - let trading_amount = BigDecimal::from_str("0.0001").unwrap(); + let dex_fee = &DexFee::Standard("0.01".into()); + let trading_amount = BigDecimal::from_str("1").unwrap(); let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); let payment_args = SendTakerFundingArgs { @@ -2113,7 +2108,7 @@ fn geth_send_approve_and_spend_eth() { }; let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 100); + wait_for_confirmations(&taker_coin, &funding_tx, 200); let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); let validate = ValidateTakerFundingArgs { @@ -2174,7 +2169,6 @@ fn geth_send_approve_and_spend_eth() { // TODO add wait_for_taker_payment_spend when it will be implemented } -#[ignore] #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { thread::sleep(Duration::from_secs(40)); @@ -2257,3 +2251,204 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { ); wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } + +#[test] +fn send_and_refund_taker_funding_exceed_payment_timelock_eth() { + // sepolia test + thread::sleep(Duration::from_secs(11)); + let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); + let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); + + let taker_secret = vec![0; 32]; + let taker_secret_hash = sha256(&taker_secret).to_vec(); + let maker_secret = vec![1; 32]; + let maker_secret_hash = sha256(&maker_secret).to_vec(); + let funding_time_lock = now_sec() + 3000; + let payment_time_lock = now_sec() - 1000; + + let taker_address = block_on(taker_coin.my_addr()); + let maker_address = block_on(maker_coin.my_addr()); + + let dex_fee = &DexFee::Standard("0.00001".into()); + let trading_amount = BigDecimal::from_str("0.0001").unwrap(); + + let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); + let payment_args = SendTakerFundingArgs { + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + maker_pub: maker_pub.as_bytes(), + dex_fee, + premium_amount: BigDecimal::default(), + trading_amount: trading_amount.clone(), + swap_unique_data: &[], + }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); + log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); + wait_for_confirmations(&taker_coin, &funding_tx, 100); + + let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); + let validate = ValidateTakerFundingArgs { + funding_tx: &funding_tx, + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + taker_pub, + dex_fee, + premium_amount: Default::default(), + trading_amount: trading_amount.clone(), + swap_unique_data: &[], + }; + wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); + block_on(maker_coin.validate_taker_funding(validate)).unwrap(); + + let approve_args = GenTakerFundingSpendArgs { + funding_tx: &funding_tx, + maker_pub, + taker_pub, + funding_time_lock, + taker_secret_hash: &taker_secret_hash, + taker_payment_time_lock: funding_time_lock, + maker_secret_hash: &maker_secret_hash, + }; + let preimage = TxPreimageWithSig { + preimage: funding_tx.clone(), + signature: taker_coin.parse_signature(&[0u8; 65]).unwrap(), + }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + let taker_approve_tx = + block_on(taker_coin.sign_and_send_taker_funding_spend(&preimage, &approve_args, &[])).unwrap(); + log!( + "Taker approved ETH payment, tx hash: {:02x}", + taker_approve_tx.tx_hash() + ); + wait_for_confirmations(&taker_coin, &taker_approve_tx, 100); + + let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { + maker_secret_hash: &maker_secret_hash, + taker_secret_hash: &taker_secret_hash, + }; + let refund_args = RefundTakerPaymentArgs { + payment_tx: &funding_tx.to_bytes(), + time_lock: payment_time_lock, + maker_pub: maker_pub.as_bytes(), + tx_type_with_secret_hash, + swap_unique_data: &[], + watcher_reward: false, + dex_fee, + premium_amount: BigDecimal::default(), + trading_amount, + }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + let funding_tx_refund = block_on(taker_coin.refund_taker_funding_timelock(refund_args)).unwrap(); + log!( + "Taker refunded ETH funding after payment lock time was exceeded, tx hash: {:02x}", + funding_tx_refund.tx_hash() + ); + wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); +} + +#[test] +fn send_and_refund_taker_funding_exceed_payment_timelock_erc20() { + // sepolia test + thread::sleep(Duration::from_secs(7)); + let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); + let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, erc20_conf, true); + let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, erc20_conf, true); + + let taker_secret = vec![0; 32]; + let taker_secret_hash = sha256(&taker_secret).to_vec(); + let maker_secret = vec![1; 32]; + let maker_secret_hash = sha256(&maker_secret).to_vec(); + let funding_time_lock = now_sec() + 29; + let payment_time_lock = now_sec() + 10; + + let taker_address = block_on(taker_coin.my_addr()); + let maker_address = block_on(maker_coin.my_addr()); + + let dex_fee = &DexFee::Standard("0.00001".into()); + let trading_amount = BigDecimal::from_str("0.0001").unwrap(); + + let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); + let payment_args = SendTakerFundingArgs { + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + maker_pub: maker_pub.as_bytes(), + dex_fee, + premium_amount: BigDecimal::default(), + trading_amount: trading_amount.clone(), + swap_unique_data: &[], + }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); + log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); + + wait_for_confirmations(&taker_coin, &funding_tx, 100); + thread::sleep(Duration::from_secs(30)); + + let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); + let validate = ValidateTakerFundingArgs { + funding_tx: &funding_tx, + funding_time_lock, + payment_time_lock, + taker_secret_hash: &taker_secret_hash, + maker_secret_hash: &maker_secret_hash, + taker_pub, + dex_fee, + premium_amount: Default::default(), + trading_amount: trading_amount.clone(), + swap_unique_data: &[], + }; + wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); + block_on(maker_coin.validate_taker_funding(validate)).unwrap(); + + let approve_args = GenTakerFundingSpendArgs { + funding_tx: &funding_tx, + maker_pub, + taker_pub, + funding_time_lock, + taker_secret_hash: &taker_secret_hash, + taker_payment_time_lock: funding_time_lock, + maker_secret_hash: &maker_secret_hash, + }; + let preimage = TxPreimageWithSig { + preimage: funding_tx.clone(), + signature: taker_coin.parse_signature(&[0u8; 65]).unwrap(), + }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + let taker_approve_tx = + block_on(taker_coin.sign_and_send_taker_funding_spend(&preimage, &approve_args, &[])).unwrap(); + log!( + "Taker approved ERC20 payment, tx hash: {:02x}", + taker_approve_tx.tx_hash() + ); + wait_for_confirmations(&taker_coin, &taker_approve_tx, 100); + + let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { + maker_secret_hash: &maker_secret_hash, + taker_secret_hash: &taker_secret_hash, + }; + let refund_args = RefundTakerPaymentArgs { + payment_tx: &funding_tx.to_bytes(), + time_lock: payment_time_lock, + maker_pub: maker_pub.as_bytes(), + tx_type_with_secret_hash, + swap_unique_data: &[], + watcher_reward: false, + dex_fee, + premium_amount: BigDecimal::default(), + trading_amount, + }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + let funding_tx_refund = block_on(taker_coin.refund_taker_funding_timelock(refund_args)).unwrap(); + log!( + "Taker refunded ERC20 funding after payment lock time was exceeded, tx hash: {:02x}", + funding_tx_refund.tx_hash() + ); + wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); +} From 89cf307c76726c22bf7a98e7f5434033f3888fb2 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 4 Aug 2024 21:24:21 +0700 Subject: [PATCH 170/233] eth tpu v2 tests: only send_and_refund_taker_funding_exceed_payment_timelock ETH/ERC20 --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 01e015ef3e..0cf38f984c 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1796,6 +1796,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } +#[ignore] #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { thread::sleep(Duration::from_secs(10)); @@ -1878,6 +1879,7 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } +#[ignore] #[test] fn send_approve_and_spend_eth() { // sepolia test @@ -1977,6 +1979,7 @@ fn send_approve_and_spend_eth() { // TODO add wait_for_taker_payment_spend when it will be implemented } +#[ignore] #[test] fn send_approve_and_spend_erc20() { // sepolia test @@ -2169,6 +2172,7 @@ fn geth_send_approve_and_spend_eth() { // TODO add wait_for_taker_payment_spend when it will be implemented } +#[ignore] #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { thread::sleep(Duration::from_secs(40)); @@ -2255,7 +2259,7 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { #[test] fn send_and_refund_taker_funding_exceed_payment_timelock_eth() { // sepolia test - thread::sleep(Duration::from_secs(11)); + thread::sleep(Duration::from_secs(3)); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); @@ -2354,7 +2358,7 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_eth() { #[test] fn send_and_refund_taker_funding_exceed_payment_timelock_erc20() { // sepolia test - thread::sleep(Duration::from_secs(7)); + thread::sleep(Duration::from_secs(32)); let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, erc20_conf, true); From 747e51ef63c24079bd261458caf3151ff7420089 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 4 Aug 2024 22:11:11 +0700 Subject: [PATCH 171/233] fix code after merge --- mm2src/coins/eth/nft_swap_v2/mod.rs | 14 +------------- mm2src/coins/lp_coins.rs | 7 ------- .../tests/docker_tests/eth_docker_tests.rs | 14 ++++---------- 3 files changed, 5 insertions(+), 30 deletions(-) diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index e1f272ecf9..ada63462b1 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -179,7 +179,7 @@ impl EthCoin { } } - pub(crate) async fn refund_nft_maker_payment_v2_secret_impl( + pub(crate) async fn refund_nft_maker_payment_v2_timelock_impl( &self, args: RefundNftMakerPaymentArgs<'_, Self>, ) -> Result { @@ -620,15 +620,3 @@ fn erc721_transfer_with_data<'a>() -> Result<&'a ethabi::Function, Erc721Functio })?; Ok(function) } - -fn validate_payment_state(tx: &SignedEthTx, state: U256, expected_state: u8) -> Result<(), PrepareTxDataError> { - if state != U256::from(expected_state) { - return Err(PrepareTxDataError::Internal(ERRL!( - "Payment {:?} state is not {}, got {}", - tx, - expected_state, - state - ))); - } - Ok(()) -} diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 41564cd24e..ca2d23dd08 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1331,13 +1331,6 @@ pub struct RefundFundingSecretArgs<'a, Coin: ParseCoinAssocTypes + ?Sized> { pub taker_secret: &'a [u8], pub taker_secret_hash: &'a [u8], pub maker_secret_hash: &'a [u8], - pub maker_secret_hash: &'a [u8], - /// DEX fee - pub dex_fee: &'a DexFee, - /// Additional reward for maker (premium) - pub premium_amount: BigDecimal, - /// Actual volume of taker's payment - pub trading_amount: BigDecimal, /// DEX fee pub dex_fee: &'a DexFee, /// Additional reward for maker (premium) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 61d427144f..116aa39756 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1639,11 +1639,10 @@ fn eth_coin_v2_activation_with_random_privkey( coin } -#[ignore] #[test] fn send_and_refund_taker_funding_by_secret_eth() { // sepolia test - thread::sleep(Duration::from_secs(25)); + thread::sleep(Duration::from_secs(6)); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); @@ -1720,7 +1719,6 @@ fn send_and_refund_taker_funding_by_secret_eth() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } -#[ignore] #[test] fn send_and_refund_taker_funding_by_secret_erc20() { let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); @@ -1799,7 +1797,6 @@ fn send_and_refund_taker_funding_by_secret_erc20() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } -#[ignore] #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { thread::sleep(Duration::from_secs(10)); @@ -1882,11 +1879,10 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } -#[ignore] #[test] fn send_approve_and_spend_eth() { // sepolia test - thread::sleep(Duration::from_secs(25)); + thread::sleep(Duration::from_secs(2)); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); @@ -1982,11 +1978,10 @@ fn send_approve_and_spend_eth() { // TODO add wait_for_taker_payment_spend when it will be implemented } -#[ignore] #[test] fn send_approve_and_spend_erc20() { // sepolia test - thread::sleep(Duration::from_secs(15)); + thread::sleep(Duration::from_secs(9)); let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, erc20_conf, true); @@ -2175,7 +2170,6 @@ fn geth_send_approve_and_spend_eth() { // TODO add wait_for_taker_payment_spend when it will be implemented } -#[ignore] #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { thread::sleep(Duration::from_secs(40)); @@ -2262,7 +2256,7 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { #[test] fn send_and_refund_taker_funding_exceed_payment_timelock_eth() { // sepolia test - thread::sleep(Duration::from_secs(3)); + thread::sleep(Duration::from_secs(25)); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); From ff00bf0bab4465de05dc620ce78d7126a6ca755b Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 5 Aug 2024 13:35:29 +0700 Subject: [PATCH 172/233] eth docker tests: remove `geth_send_approve_and_spend_eth` --- .../tests/docker_tests/eth_docker_tests.rs | 95 +------------------ 1 file changed, 1 insertion(+), 94 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 116aa39756..0b4a02ac10 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -2078,101 +2078,9 @@ fn send_approve_and_spend_erc20() { // TODO add wait_for_taker_payment_spend when it will be implemented } -#[ignore] -#[test] -fn geth_send_approve_and_spend_eth() { - thread::sleep(Duration::from_secs(3)); - let taker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init(), false); - let maker_coin = eth_coin_v2_activation_with_random_privkey(ETH, ð_dev_conf(), SwapAddresses::init(), false); - - let taker_secret = vec![0; 32]; - let taker_secret_hash = sha256(&taker_secret).to_vec(); - let maker_secret = vec![1; 32]; - let maker_secret_hash = sha256(&maker_secret).to_vec(); - let funding_time_lock = now_sec() + 3000; - let payment_time_lock = now_sec() + 1000; - - let dex_fee = &DexFee::Standard("0.01".into()); - let trading_amount = BigDecimal::from_str("1").unwrap(); - - let maker_pub = &maker_coin.derive_htlc_pubkey_v2(&[]); - let payment_args = SendTakerFundingArgs { - funding_time_lock, - payment_time_lock, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - maker_pub: maker_pub.as_bytes(), - dex_fee, - premium_amount: BigDecimal::default(), - trading_amount: trading_amount.clone(), - swap_unique_data: &[], - }; - let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); - log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 200); - - let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); - let validate = ValidateTakerFundingArgs { - funding_tx: &funding_tx, - funding_time_lock, - payment_time_lock, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - taker_pub, - dex_fee, - premium_amount: Default::default(), - trading_amount: trading_amount.clone(), - swap_unique_data: &[], - }; - block_on(maker_coin.validate_taker_funding(validate)).unwrap(); - - let approve_args = GenTakerFundingSpendArgs { - funding_tx: &funding_tx, - maker_pub, - taker_pub, - funding_time_lock, - taker_secret_hash: &taker_secret_hash, - taker_payment_time_lock: funding_time_lock, - maker_secret_hash: &maker_secret_hash, - }; - let preimage = TxPreimageWithSig { - preimage: funding_tx.clone(), - signature: taker_coin.parse_signature(&[0u8; 65]).unwrap(), - }; - let taker_approve_tx = - block_on(taker_coin.sign_and_send_taker_funding_spend(&preimage, &approve_args, &[])).unwrap(); - log!( - "Taker approved ETH payment, tx hash: {:02x}", - taker_approve_tx.tx_hash() - ); - wait_for_confirmations(&taker_coin, &taker_approve_tx, 100); - - let maker_address = block_on(maker_coin.my_addr()); - let dex_fee_pub = taker_swap_v2(); - let spend_args = GenTakerPaymentSpendArgs { - taker_tx: &taker_approve_tx, - time_lock: payment_time_lock, - maker_secret_hash: &maker_secret_hash, - maker_pub, - maker_address: &maker_address, - taker_pub, - dex_fee_pub: dex_fee_pub.as_bytes(), - dex_fee, - premium_amount: Default::default(), - trading_amount, - }; - let spend_tx = - block_on(maker_coin.sign_and_broadcast_taker_payment_spend(&preimage, &spend_args, &maker_secret, &[])) - .unwrap(); - log!("Maker spent ETH payment, tx hash: {:02x}", spend_tx.tx_hash()); - wait_for_confirmations(&maker_coin, &spend_tx, 100); - - // TODO add wait_for_taker_payment_spend when it will be implemented -} - #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { - thread::sleep(Duration::from_secs(40)); + thread::sleep(Duration::from_secs(50)); let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); @@ -2187,7 +2095,6 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { // if TakerPaymentState is `PaymentSent` then timestamp should exceed payment pre-approve lock time (funding_time_lock) let funding_time_lock = now_sec() + 29; - // TODO need to impl taker approve to test exceeded payment_time_lock let payment_time_lock = now_sec() + 1000; let dex_fee = &DexFee::Standard("0.00001".into()); From e5eef686bfa7b7f3bd70b6396a8fbbd273837d94 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 6 Aug 2024 11:01:33 +0700 Subject: [PATCH 173/233] Revert "ignore tendermint tests" This reverts commit dc215ec1b19e4e120d502c1b02365ae829fe33e4. --- mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs | 3 --- mm2src/mm2_main/tests/docker_tests_main.rs | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index cfa02420d7..3eed029dc7 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -116,11 +116,8 @@ pub const UTXO_ASSET_DOCKER_IMAGE_WITH_TAG: &str = "docker.io/artempikulin/testb pub const GETH_DOCKER_IMAGE: &str = "docker.io/ethereum/client-go"; pub const GETH_DOCKER_IMAGE_WITH_TAG: &str = "docker.io/ethereum/client-go:stable"; -#[allow(dead_code)] pub const NUCLEUS_IMAGE: &str = "docker.io/komodoofficial/nucleusd"; -#[allow(dead_code)] pub const ATOM_IMAGE: &str = "docker.io/komodoofficial/gaiad"; -#[allow(dead_code)] pub const IBC_RELAYER_IMAGE: &str = "docker.io/komodoofficial/ibc-relayer"; pub const QTUM_ADDRESS_LABEL: &str = "MM2_ADDRESS_LABEL"; diff --git a/mm2src/mm2_main/tests/docker_tests_main.rs b/mm2src/mm2_main/tests/docker_tests_main.rs index abbed46224..801e47eeb7 100644 --- a/mm2src/mm2_main/tests/docker_tests_main.rs +++ b/mm2src/mm2_main/tests/docker_tests_main.rs @@ -55,9 +55,9 @@ pub fn docker_tests_runner(tests: &[&TestDescAndFn]) { UTXO_ASSET_DOCKER_IMAGE_WITH_TAG, QTUM_REGTEST_DOCKER_IMAGE_WITH_TAG, GETH_DOCKER_IMAGE_WITH_TAG, - // NUCLEUS_IMAGE, - // ATOM_IMAGE, - // IBC_RELAYER_IMAGE, + NUCLEUS_IMAGE, + ATOM_IMAGE, + IBC_RELAYER_IMAGE, ]; for image in IMAGES { From ddbcdba22b20e0d42b7e06f37de39d4125ad9524 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 6 Aug 2024 11:01:57 +0700 Subject: [PATCH 174/233] Revert "ignore tendermint tests" This reverts commit c26c7a51154c46dcdbc808378b59e356d72459cc. --- .../tests/docker_tests/docker_tests_common.rs | 4 ---- .../tests/docker_tests/tendermint_tests.rs | 17 ----------------- mm2src/mm2_main/tests/docker_tests_main.rs | 19 +++++++++---------- 3 files changed, 9 insertions(+), 31 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 3eed029dc7..f0c21afe44 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -383,7 +383,6 @@ pub fn geth_docker_node<'a>(docker: &'a Cli, ticker: &'static str, port: u16) -> } } -#[allow(dead_code)] pub fn nucleus_node(docker: &'_ Cli, runtime_dir: PathBuf) -> DockerNode<'_> { let nucleus_node_runtime_dir = runtime_dir.join("nucleus-testnet-data"); assert!(nucleus_node_runtime_dir.exists()); @@ -400,7 +399,6 @@ pub fn nucleus_node(docker: &'_ Cli, runtime_dir: PathBuf) -> DockerNode<'_> { } } -#[allow(dead_code)] pub fn atom_node(docker: &'_ Cli, runtime_dir: PathBuf) -> DockerNode<'_> { let atom_node_runtime_dir = runtime_dir.join("atom-testnet-data"); assert!(atom_node_runtime_dir.exists()); @@ -417,7 +415,6 @@ pub fn atom_node(docker: &'_ Cli, runtime_dir: PathBuf) -> DockerNode<'_> { } } -#[allow(dead_code)] pub fn ibc_relayer_node(docker: &'_ Cli, runtime_dir: PathBuf) -> DockerNode<'_> { let relayer_node_runtime_dir = runtime_dir.join("ibc-relayer-data"); assert!(relayer_node_runtime_dir.exists()); @@ -1154,7 +1151,6 @@ async fn get_current_gas_limit(web3: &Web3) { } } -#[allow(dead_code)] pub fn wait_until_relayer_container_is_ready(container_id: &str) { const Q_RESULT: &str = "0: nucleus-atom -> chns(✔) clnts(✔) conn(✔) (nucleus-testnet<>cosmoshub-testnet)"; diff --git a/mm2src/mm2_main/tests/docker_tests/tendermint_tests.rs b/mm2src/mm2_main/tests/docker_tests/tendermint_tests.rs index 0e7e09e181..80e4470d70 100644 --- a/mm2src/mm2_main/tests/docker_tests/tendermint_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/tendermint_tests.rs @@ -21,7 +21,6 @@ const NUCLEUS_TESTNET_RPC_URLS: &[&str] = &["http://localhost:26657"]; const TENDERMINT_TEST_BIP39_SEED: &str = "emerge canoe salmon dolphin glow priority random become gasp sell blade argue"; -#[ignore] #[test] fn test_tendermint_balance() { let coins = json!([atom_testnet_conf()]); @@ -45,7 +44,6 @@ fn test_tendermint_balance() { assert_eq!(my_balance.coin, coin); } -#[ignore] #[test] fn test_tendermint_activation_without_balance() { let coins = json!([atom_testnet_conf()]); @@ -68,7 +66,6 @@ fn test_tendermint_activation_without_balance() { assert!(result.result.tokens_tickers.unwrap().is_empty()); } -#[ignore] #[test] fn test_iris_ibc_nucleus_without_balance() { let coins = json!([nucleus_testnet_conf(), iris_ibc_nucleus_testnet_conf()]); @@ -96,7 +93,6 @@ fn test_iris_ibc_nucleus_without_balance() { ); } -#[ignore] #[test] fn test_iris_ibc_nucleus_orderbook() { let coins = json!([nucleus_testnet_conf(), iris_ibc_nucleus_testnet_conf()]); @@ -145,7 +141,6 @@ fn test_iris_ibc_nucleus_orderbook() { assert_eq!(first_bid.entry.address, expected_address); } -#[ignore] #[test] fn test_tendermint_hd_address() { let coins = json!([atom_testnet_conf()]); @@ -162,7 +157,6 @@ fn test_tendermint_hd_address() { assert_eq!(result.result.address, expected_address); } -#[ignore] #[test] fn test_tendermint_withdraw() { const MY_ADDRESS: &str = "cosmos150evuj4j7k9kgu38e453jdv9m3u0ft2n53flg6"; @@ -220,7 +214,6 @@ fn test_tendermint_withdraw() { log!("Send raw tx {}", serde_json::to_string(&send_raw_tx).unwrap()); } -#[ignore] #[test] fn test_tendermint_withdraw_hd() { const MY_ADDRESS: &str = "cosmos134h9tv7866jcuw708w5w76lcfx7s3x2ysyalxy"; @@ -288,7 +281,6 @@ fn test_tendermint_withdraw_hd() { log!("Send raw tx {}", serde_json::to_string(&send_raw_tx).unwrap()); } -#[ignore] #[test] fn test_custom_gas_limit_on_tendermint_withdraw() { let coins = json!([atom_testnet_conf()]); @@ -319,7 +311,6 @@ fn test_custom_gas_limit_on_tendermint_withdraw() { assert_eq!(tx_details.fee_details["gas_limit"], 150000); } -#[ignore] #[test] fn test_tendermint_ibc_withdraw() { // visit `{swagger_address}/ibc/core/channel/v1/channels?pagination.limit=10000` to see the full list of ibc channels @@ -366,7 +357,6 @@ fn test_tendermint_ibc_withdraw() { log!("Send raw tx {}", serde_json::to_string(&send_raw_tx).unwrap()); } -#[ignore] #[test] fn test_tendermint_ibc_withdraw_hd() { // visit `{swagger_address}/ibc/core/channel/v1/channels?pagination.limit=10000` to see the full list of ibc channels @@ -414,7 +404,6 @@ fn test_tendermint_ibc_withdraw_hd() { log!("Send raw tx {}", serde_json::to_string(&send_raw_tx).unwrap()); } -#[ignore] #[test] fn test_tendermint_token_withdraw() { const MY_ADDRESS: &str = "nuc150evuj4j7k9kgu38e453jdv9m3u0ft2n4fgzfr"; @@ -495,7 +484,6 @@ fn test_tendermint_token_withdraw() { log!("Send raw tx {}", serde_json::to_string(&send_raw_tx).unwrap()); } -#[ignore] #[test] fn test_tendermint_tx_history() { const TEST_SEED: &str = "Vdo8Xt8pTAetRlMq3kV0LzE393eVYbPSn5Mhtw4p"; @@ -572,7 +560,6 @@ fn test_tendermint_tx_history() { block_on(mm.stop()).unwrap(); } -#[ignore] #[test] fn test_disable_tendermint_platform_coin_with_token() { let coins = json!([nucleus_testnet_conf(), iris_ibc_nucleus_testnet_conf()]); @@ -609,7 +596,6 @@ fn test_disable_tendermint_platform_coin_with_token() { assert!(!res.passivized); } -#[ignore] #[test] fn test_passive_coin_and_force_disable() { let coins = json!([nucleus_testnet_conf(), iris_ibc_nucleus_testnet_conf()]); @@ -686,7 +672,6 @@ mod swap { const BOB_PASSPHRASE: &str = "iris test seed"; const ALICE_PASSPHRASE: &str = "iris test2 seed"; - #[ignore] #[test] fn swap_nucleus_with_doc() { let bob_passphrase = String::from(BOB_PASSPHRASE); @@ -765,7 +750,6 @@ mod swap { )); } - #[ignore] #[test] fn swap_nucleus_with_eth() { let bob_passphrase = String::from(BOB_PASSPHRASE); @@ -872,7 +856,6 @@ mod swap { )); } - #[ignore] #[test] fn swap_doc_with_iris_ibc_nucleus() { let bob_passphrase = String::from(BOB_PASSPHRASE); diff --git a/mm2src/mm2_main/tests/docker_tests_main.rs b/mm2src/mm2_main/tests/docker_tests_main.rs index 801e47eeb7..d9c64039a0 100644 --- a/mm2src/mm2_main/tests/docker_tests_main.rs +++ b/mm2src/mm2_main/tests/docker_tests_main.rs @@ -65,11 +65,11 @@ pub fn docker_tests_runner(tests: &[&TestDescAndFn]) { remove_docker_containers(image); } - // let runtime_dir = prepare_runtime_dir().unwrap(); - // - // let nucleus_node = nucleus_node(&docker, runtime_dir.clone()); - // let atom_node = atom_node(&docker, runtime_dir.clone()); - // let ibc_relayer_node = ibc_relayer_node(&docker, runtime_dir); + let runtime_dir = prepare_runtime_dir().unwrap(); + + let nucleus_node = nucleus_node(&docker, runtime_dir.clone()); + let atom_node = atom_node(&docker, runtime_dir.clone()); + let ibc_relayer_node = ibc_relayer_node(&docker, runtime_dir); let utxo_node = utxo_asset_docker_node(&docker, "MYCOIN", 7000); let utxo_node1 = utxo_asset_docker_node(&docker, "MYCOIN1", 8000); let qtum_node = qtum_docker_node(&docker, 9000); @@ -90,16 +90,16 @@ pub fn docker_tests_runner(tests: &[&TestDescAndFn]) { wait_for_geth_node_ready(); init_geth_node(); - // wait_until_relayer_container_is_ready(ibc_relayer_node.container.id()); + wait_until_relayer_container_is_ready(ibc_relayer_node.container.id()); containers.push(utxo_node); containers.push(utxo_node1); containers.push(qtum_node); containers.push(for_slp_node); containers.push(geth_node); - // containers.push(nucleus_node); - // containers.push(atom_node); - // containers.push(ibc_relayer_node); + containers.push(nucleus_node); + containers.push(atom_node); + containers.push(ibc_relayer_node); } // detect if docker is installed // skip the tests that use docker if not installed @@ -172,7 +172,6 @@ fn remove_docker_containers(name: &str) { .expect("Failed to execute docker command"); } } -#[allow(dead_code)] fn prepare_runtime_dir() -> std::io::Result { let project_root = { let mut current_dir = std::env::current_dir().unwrap(); From c5607d881540e7ae4c31b838950124aacb49bf01 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 6 Aug 2024 15:39:07 +0700 Subject: [PATCH 175/233] polish taker_payment_approve and sign_and_broadcast_taker_payment_spend_impl funcs --- mm2src/coins/eth/eth_swap_v2.rs | 111 ++++++------------ .../tests/docker_tests/eth_docker_tests.rs | 4 +- 2 files changed, 39 insertions(+), 76 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 6b4668a3c6..4a5b03ffc6 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -219,33 +219,20 @@ impl EthCoin { &self, args: &GenTakerFundingSpendArgs<'_, Self>, ) -> Result { - let taker_swap_v2_contract = self - .swap_v2_contracts - .as_ref() - .map(|contracts| contracts.taker_swap_v2_contract) - .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; - - let (send_func, token_address) = match self.coin_type { - EthCoinType::Eth => (try_tx_s!(TAKER_SWAP_V2.function(ETH_TAKER_PAYMENT)), Address::default()), - EthCoinType::Erc20 { token_addr, .. } => { - (try_tx_s!(TAKER_SWAP_V2.function(ERC20_TAKER_PAYMENT)), token_addr) - }, - EthCoinType::Nft { .. } => { - return Err(TransactionErr::ProtocolNotSupported(ERRL!( - "NFT protocol is not supported for ETH and ERC20 Swaps" - ))) - }, - }; + let (taker_swap_v2_contract, send_func, token_address) = self + .taker_swap_v2_details(ETH_TAKER_PAYMENT, ERC20_TAKER_PAYMENT) + .await?; let decoded = try_tx_s!(decode_contract_call(send_func, args.funding_tx.unsigned().data())); + // Note: `PaymentSent` state was checked in `validate_taker_funding`. So we don't have to validate it in prepare function let data = try_tx_s!( self.prepare_taker_payment_approve_data(args, decoded, token_address) .await ); - // TODO need new consts and params for v2 calls, create provide approve const + // TODO need new consts and params for v2 calls, here should be one `gas_limit.taker_approve` param without match let gas_limit = match self.coin_type { EthCoinType::Eth => U256::from(self.gas_limit.eth_payment), EthCoinType::Erc20 { .. } => U256::from(self.gas_limit.eth_payment), - EthCoinType::Nft { .. } => unreachable!(), // EthCoinType::Nft case was already checked + EthCoinType::Nft { .. } => unreachable!(), // EthCoinType::Nft case was already checked in taker_swap_v2_details }; let approve_tx = self .sign_and_send_transaction(0.into(), Action::Call(taker_swap_v2_contract), data, gas_limit) @@ -381,46 +368,20 @@ impl EthCoin { gen_args: &GenTakerPaymentSpendArgs<'_, Self>, secret: &[u8], ) -> Result { - let taker_swap_v2_contract = self - .swap_v2_contracts - .as_ref() - .map(|contracts| contracts.taker_swap_v2_contract) - .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; - let (approve_func, token_address) = match self.coin_type { - EthCoinType::Eth => ( - try_tx_s!(TAKER_SWAP_V2.function("takerPaymentApprove")), - Address::default(), - ), - EthCoinType::Erc20 { token_addr, .. } => { - (try_tx_s!(TAKER_SWAP_V2.function("takerPaymentApprove")), token_addr) - }, - EthCoinType::Nft { .. } => { - return Err(TransactionErr::ProtocolNotSupported(ERRL!( - "NFT protocol is not supported for ETH and ERC20 Swaps" - ))) - }, - }; - let (state, decoded) = try_tx_s!( - self.status_and_decoded_from_tx_data( - taker_swap_v2_contract, - &TAKER_SWAP_V2, - approve_func, - // taker_tx should be approved tx - gen_args.taker_tx.unsigned().data(), - EthPaymentType::TakerPayments, - 3 - ) - .await - ); + let (taker_swap_v2_contract, approve_func, token_address) = self + .taker_swap_v2_details("takerPaymentApprove", "takerPaymentApprove") + .await?; + let decoded = try_tx_s!(decode_contract_call(approve_func, gen_args.taker_tx.unsigned().data())); + // Note: `TakerApproved` status will be checked in `search_for_taker_funding_spend` function let data = try_tx_s!( - self.prepare_spend_taker_payment_data(gen_args, secret, decoded, state, token_address) + self.prepare_spend_taker_payment_data(gen_args, secret, decoded, token_address) .await ); // TODO need new consts and params for v2 calls let gas_limit = match self.coin_type { EthCoinType::Eth => U256::from(self.gas_limit.eth_receiver_spend), EthCoinType::Erc20 { .. } => U256::from(self.gas_limit.erc20_receiver_spend), - EthCoinType::Nft { .. } => unreachable!(), // EthCoinType::Nft case was already checked + EthCoinType::Nft { .. } => unreachable!(), // EthCoinType::Nft case was already checked in taker_swap_v2_details }; let payment_tx = self .sign_and_send_transaction(0.into(), Action::Call(taker_swap_v2_contract), data, gas_limit) @@ -592,10 +553,8 @@ impl EthCoin { args: &GenTakerPaymentSpendArgs<'_, Self>, secret: &[u8], decoded: Vec, - state: U256, token_address: Address, ) -> Result, PrepareTxDataError> { - validate_payment_state(args.taker_tx, state, TakerPaymentStateV2::TakerApproved as u8)?; let function = TAKER_SWAP_V2.function("spendTakerPayment")?; let taker_address = public_to_address(args.taker_pub); let data = function.encode_input(&[ @@ -642,28 +601,30 @@ impl EthCoin { } } - /// Returns payment status and decoded tx input from bytes of contract call - async fn status_and_decoded_from_tx_data( + /// Retrieves the taker smart contract address, the corresponding function, and the token address. + /// + /// Depending on the coin type (ETH or ERC20), it fetches the appropriate function name and token address. + /// Returns an error if the coin type is NFT or if the `swap_v2_contracts` is None. + async fn taker_swap_v2_details( &self, - swap_address: Address, - contract_abi: &Contract, - func: &Function, - contract_call_bytes: &[u8], - payment_type: EthPaymentType, - state_index: usize, - ) -> Result<(U256, Vec), PaymentStatusErr> { - let decoded = decode_contract_call(func, contract_call_bytes)?; - let state = self - .payment_status_v2( - swap_address, - // swap_id has 0 index - decoded[0].clone(), - contract_abi, - payment_type, - state_index, - ) - .await?; - Ok((state, decoded)) + eth_func_name: &str, + erc20_func_name: &str, + ) -> Result<(Address, &Function, Address), TransactionErr> { + let taker_swap_v2_contract = self + .swap_v2_contracts + .as_ref() + .map(|contracts| contracts.taker_swap_v2_contract) + .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; + let (func, token_address) = match self.coin_type { + EthCoinType::Eth => (try_tx_s!(TAKER_SWAP_V2.function(eth_func_name)), Address::default()), + EthCoinType::Erc20 { token_addr, .. } => (try_tx_s!(TAKER_SWAP_V2.function(erc20_func_name)), token_addr), + EthCoinType::Nft { .. } => { + return Err(TransactionErr::ProtocolNotSupported(ERRL!( + "NFT protocol is not supported for ETH and ERC20 Swaps" + ))) + }, + }; + Ok((taker_swap_v2_contract, func, token_address)) } } diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 0b4a02ac10..0405bd7911 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1789,6 +1789,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { watcher_reward: false, }; wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + thread::sleep(Duration::from_secs(1)); let funding_tx_refund = block_on(taker_coin.refund_taker_funding_secret(refund_args)).unwrap(); log!( "Taker refunded ERC20 funding by secret, tx hash: {:02x}", @@ -1799,7 +1800,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { - thread::sleep(Duration::from_secs(10)); + thread::sleep(Duration::from_secs(12)); // sepolia test let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); @@ -2152,6 +2153,7 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { trading_amount, }; wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + thread::sleep(Duration::from_secs(3)); let funding_tx_refund = block_on(taker_coin.refund_taker_funding_timelock(refund_args)).unwrap(); log!( "Taker refunded ERC20 funding after pre-approval lock time was exceeded, tx hash: {:02x}", From 8d33bfefdbf9bf67f0f5c599b4b4b60d7892de9e Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 6 Aug 2024 19:43:04 +0700 Subject: [PATCH 176/233] eth tpu v2: search_for_taker_funding_spend implemented --- mm2src/coins/eth.rs | 6 +-- mm2src/coins/eth/eth_swap_v2.rs | 49 ++++++++++++++++++-- mm2src/coins/lp_coins.rs | 1 + mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs | 3 +- 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index d10f43e525..f15d67e31a 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7097,14 +7097,14 @@ impl TakerCoinSwapOpsV2 for EthCoin { self.refund_taker_funding_secret_impl(args).await } - /// Checks taker payment status in etomic swap contract + /// Check if taker payment state is `TakerApproved` async fn search_for_taker_funding_spend( &self, - _tx: &Self::Tx, + tx: &Self::Tx, _from_block: u64, _secret_hash: &[u8], ) -> Result>, SearchForFundingSpendErr> { - todo!() + self.search_for_taker_funding_spend_impl(tx).await } /// Eth doesnt have preimages diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 4a5b03ffc6..3c7679d2fb 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -2,7 +2,7 @@ use super::eth::{wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_ use super::{decode_contract_call, get_function_input_data, ParseCoinAssocTypes, RefundFundingSecretArgs, RefundTakerPaymentArgs, SendTakerFundingArgs, SwapTxTypeWithSecretHash, TakerPaymentStateV2, Transaction, TransactionErr, ValidateSwapV2TxError, ValidateSwapV2TxResult, ValidateTakerFundingArgs}; -use crate::{GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs}; +use crate::{FundingTxSpend, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, SearchForFundingSpendErr}; use enum_derives::EnumFromStringify; use ethabi::{Contract, Function, Token}; use ethcore_transaction::Action; @@ -17,6 +17,7 @@ use web3::types::{Transaction as Web3Tx, TransactionId}; const ETH_TAKER_PAYMENT: &str = "ethTakerPayment"; const ERC20_TAKER_PAYMENT: &str = "erc20TakerPayment"; +const TAKER_PAYMENT_APPROVE: &str = "takerPaymentApprove"; struct TakerFundingArgs { dex_fee: U256, @@ -363,16 +364,56 @@ impl EthCoin { .await } + /// Check if taker payment state is `TakerApproved` + pub(crate) async fn search_for_taker_funding_spend_impl( + &self, + tx: &SignedEthTx, + ) -> Result>, SearchForFundingSpendErr> { + let taker_swap_v2_contract = self + .swap_v2_contracts + .as_ref() + .map(|contracts| contracts.taker_swap_v2_contract) + .ok_or_else(|| { + SearchForFundingSpendErr::Internal(ERRL!("Expected swap_v2_contracts to be Some, but found None")) + })?; + let approve_func = match self.coin_type { + EthCoinType::Eth | EthCoinType::Erc20 { .. } => TAKER_SWAP_V2 + .function(TAKER_PAYMENT_APPROVE) + .map_err(|e| SearchForFundingSpendErr::Internal(ERRL!("{}", e)))?, + EthCoinType::Nft { .. } => { + return Err(SearchForFundingSpendErr::Internal(ERRL!( + "NFT protocol is not supported for ETH and ERC20 Swaps" + ))) + }, + }; + let decoded = decode_contract_call(approve_func, tx.unsigned().data()) + .map_err(|e| SearchForFundingSpendErr::Internal(ERRL!("Failed to decode tx data:{}", e)))?; + let taker_status = self + .payment_status_v2( + taker_swap_v2_contract, + decoded[0].clone(), // id from takerPaymentApprove + &TAKER_SWAP_V2, + EthPaymentType::TakerPayments, + 3, + ) + .await + .map_err(|e| SearchForFundingSpendErr::Internal(ERRL!("{}", e)))?; + if taker_status == U256::from(TakerPaymentStateV2::TakerApproved as u8) { + return Ok(Some(FundingTxSpend::TransferredToTakerPayment(tx.clone()))); + } + Ok(None) + } + pub(crate) async fn sign_and_broadcast_taker_payment_spend_impl( &self, gen_args: &GenTakerPaymentSpendArgs<'_, Self>, secret: &[u8], ) -> Result { let (taker_swap_v2_contract, approve_func, token_address) = self - .taker_swap_v2_details("takerPaymentApprove", "takerPaymentApprove") + .taker_swap_v2_details(TAKER_PAYMENT_APPROVE, TAKER_PAYMENT_APPROVE) .await?; let decoded = try_tx_s!(decode_contract_call(approve_func, gen_args.taker_tx.unsigned().data())); - // Note: `TakerApproved` status will be checked in `search_for_taker_funding_spend` function + // Note: `TakerApproved` status was checked in `search_for_taker_funding_spend` function let data = try_tx_s!( self.prepare_spend_taker_payment_data(gen_args, secret, decoded, token_address) .await @@ -507,7 +548,7 @@ impl EthCoin { decoded: Vec, token_address: Address, ) -> Result, PrepareTxDataError> { - let function = TAKER_SWAP_V2.function("takerPaymentApprove")?; + let function = TAKER_SWAP_V2.function(TAKER_PAYMENT_APPROVE)?; let data = match self.coin_type { EthCoinType::Eth => { let dex_fee = match &decoded[1] { diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index ca2d23dd08..5b40fd9328 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1900,6 +1900,7 @@ pub enum SearchForFundingSpendErr { Rpc(String), /// Variant indicating an error during conversion of the `from_block` argument with associated `TryFromIntError`. FromBlockConversionErr(TryFromIntError), + Internal(String), } /// Operations specific to taker coin in [Trading Protocol Upgrade implementation](https://github.com/KomodoPlatform/komodo-defi-framework/issues/1895) diff --git a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs index de8665ba3e..0f58bf68e7 100644 --- a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs @@ -1358,7 +1358,8 @@ impl { + | e @ SearchForFundingSpendErr::FromBlockConversionErr(_) + | e @ SearchForFundingSpendErr::Internal(_) => { let next_state = MakerPaymentRefundRequired { maker_coin_start_block: self.maker_coin_start_block, taker_coin_start_block: self.taker_coin_start_block, From 5e3e0fd87e7d023b70f1689eefbf219e95622b0d Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 8 Aug 2024 19:50:27 +0700 Subject: [PATCH 177/233] review fixes --- mm2src/coins/eth.rs | 33 +------------- mm2src/coins/eth/nft_swap_v2/mod.rs | 8 ++-- .../tests/docker_tests/eth_docker_tests.rs | 44 +++++++------------ mm2src/mm2_test_helpers/src/for_tests.rs | 36 +++------------ 4 files changed, 29 insertions(+), 92 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index f15d67e31a..39656bc205 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7218,36 +7218,5 @@ impl CommonSwapOpsV2 for EthCoin { #[cfg(all(feature = "for-tests", not(target_arch = "wasm32")))] impl EthCoin { - pub async fn set_coin_type(&self, new_coin_type: EthCoinType) -> EthCoin { - let coin = EthCoinImpl { - ticker: self.ticker.clone(), - coin_type: new_coin_type, - priv_key_policy: self.priv_key_policy.clone(), - derivation_method: Arc::clone(&self.derivation_method), - sign_message_prefix: self.sign_message_prefix.clone(), - swap_contract_address: self.swap_contract_address, - swap_v2_contracts: self.swap_v2_contracts, - fallback_swap_contract: self.fallback_swap_contract, - contract_supports_watchers: self.contract_supports_watchers, - web3_instances: AsyncMutex::new(self.web3_instances.lock().await.clone()), - decimals: self.decimals, - history_sync_state: Mutex::new(self.history_sync_state.lock().unwrap().clone()), - required_confirmations: AtomicU64::new( - self.required_confirmations.load(std::sync::atomic::Ordering::SeqCst), - ), - swap_txfee_policy: Mutex::new(self.swap_txfee_policy.lock().unwrap().clone()), - max_eth_tx_type: self.max_eth_tx_type, - ctx: self.ctx.clone(), - chain_id: self.chain_id, - trezor_coin: self.trezor_coin.clone(), - logs_block_range: self.logs_block_range, - address_nonce_locks: Arc::clone(&self.address_nonce_locks), - erc20_tokens_infos: Arc::clone(&self.erc20_tokens_infos), - nfts_infos: Arc::clone(&self.nfts_infos), - platform_fee_estimator_state: Arc::clone(&self.platform_fee_estimator_state), - gas_limit: EthGasLimit::default(), - abortable_system: self.abortable_system.create_subsystem().unwrap(), - }; - EthCoin(Arc::new(coin)) - } + pub fn set_coin_type(&mut self, new_coin_type: EthCoinType) { self.coin_type = new_coin_type; } } diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index ada63462b1..1c707d9b6e 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -47,7 +47,7 @@ impl EthCoin { .await }, EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported(ERRL!( - "ETH and ERC20 Protocols are not supported for NFT Swaps" + "ETH and ERC20 protocols are not supported for NFT swaps." ))), } } @@ -174,7 +174,7 @@ impl EthCoin { .await }, EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported(ERRL!( - "ETH and ERC20 Protocols are not supported for NFT Swaps" + "ETH and ERC20 protocols are not supported for NFT swaps." ))), } } @@ -214,7 +214,7 @@ impl EthCoin { .await }, EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported(ERRL!( - "ETH and ERC20 Protocols are not supported for NFT Swaps" + "ETH and ERC20 protocols are not supported for NFT swaps." ))), } } @@ -255,7 +255,7 @@ impl EthCoin { .await }, EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported(ERRL!( - "ETH and ERC20 Protocols are not supported for NFT Swaps" + "ETH and ERC20 protocols are not supported for NFT swaps." ))), } } diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 0405bd7911..192b4abd14 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -28,7 +28,7 @@ use futures01::Future; use mm2_core::mm_ctx::MmArc; use mm2_number::{BigDecimal, BigUint}; use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, eth_sepolia_conf, nft_dev_conf, nft_sepolia_conf, - seploia_erc20_dev_conf}; + sepolia_erc20_dev_conf}; use serde_json::Value as Json; use std::str::FromStr; use std::thread; @@ -430,7 +430,7 @@ fn global_nft_with_random_privkey( gap_limit: None, }; - let coin = block_on(eth_coin_from_conf_and_request_v2( + let mut coin = block_on(eth_coin_from_conf_and_request_v2( &MM_CTX1, nft_ticker.as_str(), &nft_dev_conf(), @@ -442,31 +442,24 @@ fn global_nft_with_random_privkey( let coin_type = EthCoinType::Nft { platform: platform_ticker, }; + coin.set_coin_type(coin_type); - let global_nft = block_on(coin.set_coin_type(coin_type)); - - let my_address = block_on(global_nft.my_addr()); + let my_address = block_on(coin.my_addr()); fill_eth(my_address, U256::from(10).pow(U256::from(20))); if let Some(nft_type) = nft_type { match nft_type { TestNftType::Erc1155 { token_id, amount } => { mint_erc1155(my_address, U256::from(token_id), U256::from(amount)); - block_on(fill_erc1155_info( - &global_nft, - geth_erc1155_contract(), - token_id, - amount, - )); + block_on(fill_erc1155_info(&coin, geth_erc1155_contract(), token_id, amount)); }, TestNftType::Erc721 { token_id } => { mint_erc721(my_address, U256::from(token_id)); - block_on(fill_erc721_info(&global_nft, geth_erc721_contract(), token_id)); + block_on(fill_erc721_info(&coin, geth_erc721_contract(), token_id)); }, } } - - global_nft + coin } #[allow(dead_code)] @@ -554,7 +547,7 @@ fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, co gap_limit: None, }; - let coin = block_on(eth_coin_from_conf_and_request_v2( + let mut coin = block_on(eth_coin_from_conf_and_request_v2( ctx, ticker, conf, @@ -562,15 +555,13 @@ fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, co build_policy, )) .unwrap(); - let coin = if erc20 { + if erc20 { let coin_type = EthCoinType::Erc20 { platform: ETH.to_string(), token_addr: sepolia_erc20_contract(), }; - block_on(coin.set_coin_type(coin_type)) - } else { - coin - }; + coin.set_coin_type(coin_type); + } let coins_ctx = CoinsContext::from_ctx(ctx).unwrap(); let mut coins = block_on(coins_ctx.lock_coins()); @@ -1617,7 +1608,7 @@ fn eth_coin_v2_activation_with_random_privkey( path_to_address: Default::default(), gap_limit: None, }; - let coin = block_on(eth_coin_from_conf_and_request_v2( + let mut coin = block_on(eth_coin_from_conf_and_request_v2( &MM_CTX1, ticker, conf, @@ -1633,8 +1624,7 @@ fn eth_coin_v2_activation_with_random_privkey( platform: ETH.to_string(), token_addr: erc20_contract(), }; - let coin = block_on(coin.set_coin_type(coin_type)); - return coin; + coin.set_coin_type(coin_type); } coin } @@ -1721,7 +1711,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { #[test] fn send_and_refund_taker_funding_by_secret_erc20() { - let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); + let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); @@ -1983,7 +1973,7 @@ fn send_approve_and_spend_eth() { fn send_approve_and_spend_erc20() { // sepolia test thread::sleep(Duration::from_secs(9)); - let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); + let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, erc20_conf, true); @@ -2082,7 +2072,7 @@ fn send_approve_and_spend_erc20() { #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { thread::sleep(Duration::from_secs(50)); - let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); + let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); @@ -2265,7 +2255,7 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_eth() { fn send_and_refund_taker_funding_exceed_payment_timelock_erc20() { // sepolia test thread::sleep(Duration::from_secs(32)); - let erc20_conf = &seploia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); + let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, erc20_conf, true); diff --git a/mm2src/mm2_test_helpers/src/for_tests.rs b/mm2src/mm2_test_helpers/src/for_tests.rs index 11537c3fb4..e4049a10bc 100644 --- a/mm2src/mm2_test_helpers/src/for_tests.rs +++ b/mm2src/mm2_test_helpers/src/for_tests.rs @@ -829,22 +829,10 @@ pub fn erc20_dev_conf(contract_address: &str) -> Json { } /// ERC20 token configuration used for dockerized tests on Sepolia -pub fn seploia_erc20_dev_conf(contract_address: &str) -> Json { - json!({ - "coin": "ERC20DEV", - "name": "erc20dev", - "chain_id": 11155111, - "mm2": 1, - "derivation_path": "m/44'/60'", - "protocol": { - "type": "ERC20", - "protocol_data": { - "platform": "ETH", - "contract_address": contract_address, - } - }, - "max_eth_tx_type": 2 - }) +pub fn sepolia_erc20_dev_conf(contract_address: &str) -> Json { + let mut conf = erc20_dev_conf(contract_address); + conf["chain_id"] = json!(11155111); + conf } /// global NFT configuration used for dockerized Geth dev node @@ -867,19 +855,9 @@ pub fn nft_dev_conf() -> Json { /// global NFT configuration used for Sepolia testnet pub fn nft_sepolia_conf() -> Json { - json!({ - "coin": "NFT_ETH", - "name": "nftdev", - "chain_id": 11155111, - "mm2": 1, - "derivation_path": "m/44'/60'", - "protocol": { - "type": "NFT", - "protocol_data": { - "platform": "ETH" - } - } - }) + let mut conf = nft_dev_conf(); + conf["chain_id"] = json!(11155111); + conf } pub fn eth_sepolia_conf() -> Json { From 8b8e0a5063647a2fda87d2d3a8598c50d77bb6dc Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 8 Aug 2024 20:01:31 +0700 Subject: [PATCH 178/233] use Arc mut --- mm2src/coins/eth.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 39656bc205..15e3711a81 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7218,5 +7218,12 @@ impl CommonSwapOpsV2 for EthCoin { #[cfg(all(feature = "for-tests", not(target_arch = "wasm32")))] impl EthCoin { - pub fn set_coin_type(&mut self, new_coin_type: EthCoinType) { self.coin_type = new_coin_type; } + pub fn set_coin_type(&mut self, new_coin_type: EthCoinType) { + if let Some(inner) = Arc::get_mut(&mut self.0) { + inner.coin_type = new_coin_type; + } else { + let mut inner = Arc::make_mut(&mut self.0); + inner.coin_type = new_coin_type; + } + } } From 4e1352dfc2386bf25f2dcefbdee4bd4634a2fc3a Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 8 Aug 2024 20:14:46 +0700 Subject: [PATCH 179/233] return old set_coin_type --- mm2src/coins/eth.rs | 38 +++++++++++++++---- .../tests/docker_tests/eth_docker_tests.rs | 31 +++++++++------ 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 15e3711a81..f15d67e31a 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7218,12 +7218,36 @@ impl CommonSwapOpsV2 for EthCoin { #[cfg(all(feature = "for-tests", not(target_arch = "wasm32")))] impl EthCoin { - pub fn set_coin_type(&mut self, new_coin_type: EthCoinType) { - if let Some(inner) = Arc::get_mut(&mut self.0) { - inner.coin_type = new_coin_type; - } else { - let mut inner = Arc::make_mut(&mut self.0); - inner.coin_type = new_coin_type; - } + pub async fn set_coin_type(&self, new_coin_type: EthCoinType) -> EthCoin { + let coin = EthCoinImpl { + ticker: self.ticker.clone(), + coin_type: new_coin_type, + priv_key_policy: self.priv_key_policy.clone(), + derivation_method: Arc::clone(&self.derivation_method), + sign_message_prefix: self.sign_message_prefix.clone(), + swap_contract_address: self.swap_contract_address, + swap_v2_contracts: self.swap_v2_contracts, + fallback_swap_contract: self.fallback_swap_contract, + contract_supports_watchers: self.contract_supports_watchers, + web3_instances: AsyncMutex::new(self.web3_instances.lock().await.clone()), + decimals: self.decimals, + history_sync_state: Mutex::new(self.history_sync_state.lock().unwrap().clone()), + required_confirmations: AtomicU64::new( + self.required_confirmations.load(std::sync::atomic::Ordering::SeqCst), + ), + swap_txfee_policy: Mutex::new(self.swap_txfee_policy.lock().unwrap().clone()), + max_eth_tx_type: self.max_eth_tx_type, + ctx: self.ctx.clone(), + chain_id: self.chain_id, + trezor_coin: self.trezor_coin.clone(), + logs_block_range: self.logs_block_range, + address_nonce_locks: Arc::clone(&self.address_nonce_locks), + erc20_tokens_infos: Arc::clone(&self.erc20_tokens_infos), + nfts_infos: Arc::clone(&self.nfts_infos), + platform_fee_estimator_state: Arc::clone(&self.platform_fee_estimator_state), + gas_limit: EthGasLimit::default(), + abortable_system: self.abortable_system.create_subsystem().unwrap(), + }; + EthCoin(Arc::new(coin)) } } diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 192b4abd14..967d3e0a2f 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -430,7 +430,7 @@ fn global_nft_with_random_privkey( gap_limit: None, }; - let mut coin = block_on(eth_coin_from_conf_and_request_v2( + let coin = block_on(eth_coin_from_conf_and_request_v2( &MM_CTX1, nft_ticker.as_str(), &nft_dev_conf(), @@ -442,8 +442,7 @@ fn global_nft_with_random_privkey( let coin_type = EthCoinType::Nft { platform: platform_ticker, }; - coin.set_coin_type(coin_type); - + let global_nft = block_on(coin.set_coin_type(coin_type)); let my_address = block_on(coin.my_addr()); fill_eth(my_address, U256::from(10).pow(U256::from(20))); @@ -451,15 +450,20 @@ fn global_nft_with_random_privkey( match nft_type { TestNftType::Erc1155 { token_id, amount } => { mint_erc1155(my_address, U256::from(token_id), U256::from(amount)); - block_on(fill_erc1155_info(&coin, geth_erc1155_contract(), token_id, amount)); + block_on(fill_erc1155_info( + &global_nft, + geth_erc1155_contract(), + token_id, + amount, + )); }, TestNftType::Erc721 { token_id } => { mint_erc721(my_address, U256::from(token_id)); - block_on(fill_erc721_info(&coin, geth_erc721_contract(), token_id)); + block_on(fill_erc721_info(&global_nft, geth_erc721_contract(), token_id)); }, } } - coin + global_nft } #[allow(dead_code)] @@ -547,7 +551,7 @@ fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, co gap_limit: None, }; - let mut coin = block_on(eth_coin_from_conf_and_request_v2( + let coin = block_on(eth_coin_from_conf_and_request_v2( ctx, ticker, conf, @@ -555,13 +559,15 @@ fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, co build_policy, )) .unwrap(); - if erc20 { + let coin = if erc20 { let coin_type = EthCoinType::Erc20 { platform: ETH.to_string(), token_addr: sepolia_erc20_contract(), }; - coin.set_coin_type(coin_type); - } + block_on(coin.set_coin_type(coin_type)) + } else { + coin + }; let coins_ctx = CoinsContext::from_ctx(ctx).unwrap(); let mut coins = block_on(coins_ctx.lock_coins()); @@ -1608,7 +1614,7 @@ fn eth_coin_v2_activation_with_random_privkey( path_to_address: Default::default(), gap_limit: None, }; - let mut coin = block_on(eth_coin_from_conf_and_request_v2( + let coin = block_on(eth_coin_from_conf_and_request_v2( &MM_CTX1, ticker, conf, @@ -1624,7 +1630,8 @@ fn eth_coin_v2_activation_with_random_privkey( platform: ETH.to_string(), token_addr: erc20_contract(), }; - coin.set_coin_type(coin_type); + let coin = block_on(coin.set_coin_type(coin_type)); + return coin; } coin } From 467a421cc971fbdb7e9ae642d9c56c7759bbdd85 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 9 Aug 2024 15:08:08 +0700 Subject: [PATCH 180/233] review: create decoded variable within an inner scope, From for RefundPaymentArgs --- mm2src/coins/eth/eth_swap_v2.rs | 48 +++++++++++++++++------------- mm2src/coins/lp_coins.rs | 14 +++++++++ mm2src/coins/utxo/utxo_standard.rs | 22 ++------------ 3 files changed, 43 insertions(+), 41 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 3c7679d2fb..42cd802a42 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -223,12 +223,14 @@ impl EthCoin { let (taker_swap_v2_contract, send_func, token_address) = self .taker_swap_v2_details(ETH_TAKER_PAYMENT, ERC20_TAKER_PAYMENT) .await?; - let decoded = try_tx_s!(decode_contract_call(send_func, args.funding_tx.unsigned().data())); // Note: `PaymentSent` state was checked in `validate_taker_funding`. So we don't have to validate it in prepare function - let data = try_tx_s!( - self.prepare_taker_payment_approve_data(args, decoded, token_address) - .await - ); + let data = { + let decoded = try_tx_s!(decode_contract_call(send_func, args.funding_tx.unsigned().data())); + try_tx_s!( + self.prepare_taker_payment_approve_data(args, decoded, token_address) + .await + ) + }; // TODO need new consts and params for v2 calls, here should be one `gas_limit.taker_approve` param without match let gas_limit = match self.coin_type { EthCoinType::Eth => U256::from(self.gas_limit.eth_payment), @@ -376,18 +378,20 @@ impl EthCoin { .ok_or_else(|| { SearchForFundingSpendErr::Internal(ERRL!("Expected swap_v2_contracts to be Some, but found None")) })?; - let approve_func = match self.coin_type { - EthCoinType::Eth | EthCoinType::Erc20 { .. } => TAKER_SWAP_V2 - .function(TAKER_PAYMENT_APPROVE) - .map_err(|e| SearchForFundingSpendErr::Internal(ERRL!("{}", e)))?, - EthCoinType::Nft { .. } => { - return Err(SearchForFundingSpendErr::Internal(ERRL!( - "NFT protocol is not supported for ETH and ERC20 Swaps" - ))) - }, + let decoded = { + let approve_func = match self.coin_type { + EthCoinType::Eth | EthCoinType::Erc20 { .. } => TAKER_SWAP_V2 + .function(TAKER_PAYMENT_APPROVE) + .map_err(|e| SearchForFundingSpendErr::Internal(ERRL!("{}", e)))?, + EthCoinType::Nft { .. } => { + return Err(SearchForFundingSpendErr::Internal(ERRL!( + "NFT protocol is not supported for ETH and ERC20 Swaps" + ))) + }, + }; + decode_contract_call(approve_func, tx.unsigned().data()) + .map_err(|e| SearchForFundingSpendErr::Internal(ERRL!("Failed to decode tx data:{}", e)))? }; - let decoded = decode_contract_call(approve_func, tx.unsigned().data()) - .map_err(|e| SearchForFundingSpendErr::Internal(ERRL!("Failed to decode tx data:{}", e)))?; let taker_status = self .payment_status_v2( taker_swap_v2_contract, @@ -412,12 +416,14 @@ impl EthCoin { let (taker_swap_v2_contract, approve_func, token_address) = self .taker_swap_v2_details(TAKER_PAYMENT_APPROVE, TAKER_PAYMENT_APPROVE) .await?; - let decoded = try_tx_s!(decode_contract_call(approve_func, gen_args.taker_tx.unsigned().data())); // Note: `TakerApproved` status was checked in `search_for_taker_funding_spend` function - let data = try_tx_s!( - self.prepare_spend_taker_payment_data(gen_args, secret, decoded, token_address) - .await - ); + let data = { + let decoded = try_tx_s!(decode_contract_call(approve_func, gen_args.taker_tx.unsigned().data())); + try_tx_s!( + self.prepare_spend_taker_payment_data(gen_args, secret, decoded, token_address) + .await + ) + }; // TODO need new consts and params for v2 calls let gas_limit = match self.coin_type { EthCoinType::Eth => U256::from(self.gas_limit.eth_receiver_spend), diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 5b40fd9328..9502a88633 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1006,6 +1006,20 @@ pub struct RefundTakerPaymentArgs<'a> { pub trading_amount: BigDecimal, } +impl<'a> From> for RefundPaymentArgs<'a> { + fn from(args: RefundTakerPaymentArgs<'a>) -> RefundPaymentArgs<'a> { + RefundPaymentArgs { + payment_tx: args.payment_tx, + time_lock: args.time_lock, + other_pubkey: args.maker_pub, + tx_type_with_secret_hash: args.tx_type_with_secret_hash, + swap_contract_address: &None, + swap_unique_data: args.swap_unique_data, + watcher_reward: args.watcher_reward, + } + } +} + /// Helper struct wrapping arguments for [SwapOps::check_if_my_payment_sent]. #[derive(Clone, Debug)] pub struct CheckIfMyPaymentSentArgs<'a> { diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index 062545b587..2753b7b1b4 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -667,16 +667,7 @@ impl TakerCoinSwapOpsV2 for UtxoStandardCoin { &self, args: RefundTakerPaymentArgs<'_>, ) -> Result { - let args = RefundPaymentArgs { - payment_tx: args.payment_tx, - time_lock: args.time_lock, - other_pubkey: args.maker_pub, - tx_type_with_secret_hash: args.tx_type_with_secret_hash, - swap_contract_address: &None, - swap_unique_data: args.swap_unique_data, - watcher_reward: args.watcher_reward, - }; - utxo_common::refund_htlc_payment(self.clone(), args).await + utxo_common::refund_htlc_payment(self.clone(), args.into()).await } async fn refund_taker_funding_secret( @@ -791,16 +782,7 @@ impl TakerCoinSwapOpsV2 for UtxoStandardCoin { &self, args: RefundTakerPaymentArgs<'_>, ) -> Result { - let args = RefundPaymentArgs { - payment_tx: args.payment_tx, - time_lock: args.time_lock, - other_pubkey: args.maker_pub, - tx_type_with_secret_hash: args.tx_type_with_secret_hash, - swap_contract_address: &None, - swap_unique_data: args.swap_unique_data, - watcher_reward: args.watcher_reward, - }; - utxo_common::refund_htlc_payment(self.clone(), args).await + utxo_common::refund_htlc_payment(self.clone(), args.into()).await } async fn gen_taker_payment_spend_preimage( From 284fc0f4794cde4f002d0483f3330bc32796b2a4 Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 9 Aug 2024 15:13:48 +0700 Subject: [PATCH 181/233] use checked_add for eth_total_payment calculation --- mm2src/coins/eth/eth_swap_v2.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 42cd802a42..b303e959ad 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -83,7 +83,9 @@ impl EthCoin { match &self.coin_type { EthCoinType::Eth => { let data = try_tx_s!(self.prepare_taker_eth_funding_data(&funding_args).await); - let eth_total_payment = dex_fee + payment_amount; + let eth_total_payment = payment_amount.checked_add(dex_fee).ok_or_else(|| { + TransactionErr::Plain(ERRL!("Overflow occurred while calculating eth_total_payment")) + })?; self.sign_and_send_transaction( eth_total_payment, Action::Call(taker_swap_v2_contract), From 9f3164995bd463227c570ad9bbd890e3103142ec Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 12 Aug 2024 11:47:35 +0700 Subject: [PATCH 182/233] review: change error type, move match coin_type to the top, update maker/taker coin doc coms. --- mm2src/coins/eth/eth_swap_v2.rs | 94 +++++++++++--------- mm2src/coins/lp_coins.rs | 6 +- mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs | 6 +- mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 6 +- 4 files changed, 65 insertions(+), 47 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index b303e959ad..c84527174f 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -140,8 +140,8 @@ impl EthCoin { args: ValidateTakerFundingArgs<'_, Self>, ) -> ValidateSwapV2TxResult { if let EthCoinType::Nft { .. } = self.coin_type { - return MmError::err(ValidateSwapV2TxError::Internal( - "EthCoinType must be ETH or ERC20".to_string(), + return MmError::err(ValidateSwapV2TxError::ProtocolNotSupported( + "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), )); } let taker_swap_v2_contract = self @@ -222,6 +222,16 @@ impl EthCoin { &self, args: &GenTakerFundingSpendArgs<'_, Self>, ) -> Result { + // TODO need new consts and params for v2 calls, here should be common `gas_limit.taker_approve` param for Eth and Erc20 + let gas_limit = match self.coin_type { + EthCoinType::Eth => U256::from(self.gas_limit.eth_payment), + EthCoinType::Erc20 { .. } => U256::from(self.gas_limit.eth_payment), + EthCoinType::Nft { .. } => { + return Err(TransactionErr::ProtocolNotSupported(ERRL!( + "NFT protocol is not supported for ETH and ERC20 Swaps" + ))) + }, + }; let (taker_swap_v2_contract, send_func, token_address) = self .taker_swap_v2_details(ETH_TAKER_PAYMENT, ERC20_TAKER_PAYMENT) .await?; @@ -233,12 +243,6 @@ impl EthCoin { .await ) }; - // TODO need new consts and params for v2 calls, here should be one `gas_limit.taker_approve` param without match - let gas_limit = match self.coin_type { - EthCoinType::Eth => U256::from(self.gas_limit.eth_payment), - EthCoinType::Erc20 { .. } => U256::from(self.gas_limit.eth_payment), - EthCoinType::Nft { .. } => unreachable!(), // EthCoinType::Nft case was already checked in taker_swap_v2_details - }; let approve_tx = self .sign_and_send_transaction(0.into(), Action::Call(taker_swap_v2_contract), data, gas_limit) .compat() @@ -250,6 +254,20 @@ impl EthCoin { &self, args: RefundTakerPaymentArgs<'_>, ) -> Result { + let (token_address, gas_limit) = match &self.coin_type { + // TODO need new consts and params for v2 calls + EthCoinType::Eth => (Address::default(), self.gas_limit.eth_sender_refund), + EthCoinType::Erc20 { + platform: _, + token_addr, + } => (*token_addr, self.gas_limit.erc20_sender_refund), + EthCoinType::Nft { .. } => { + return Err(TransactionErr::ProtocolNotSupported(ERRL!( + "NFT protocol is not supported for ETH and ERC20 Swaps" + ))) + }, + }; + let taker_swap_v2_contract = self .swap_v2_contracts .as_ref() @@ -277,20 +295,6 @@ impl EthCoin { }, }; - let (token_address, gas_limit) = match &self.coin_type { - // TODO need new consts and params for v2 calls. now it uses v1 - EthCoinType::Eth => (Address::default(), self.gas_limit.eth_sender_refund), - EthCoinType::Erc20 { - platform: _, - token_addr, - // TODO need new consts and params for v2 calls. now it uses v1 - } => (*token_addr, self.gas_limit.erc20_sender_refund), - EthCoinType::Nft { .. } => { - return Err(TransactionErr::ProtocolNotSupported(ERRL!( - "NFT protocol is not supported for ETH and ERC20 Swaps" - ))) - }, - }; let args = TakerRefundArgs { dex_fee, payment_amount, @@ -316,6 +320,20 @@ impl EthCoin { &self, args: RefundFundingSecretArgs<'_, Self>, ) -> Result { + let (token_address, gas_limit) = match &self.coin_type { + // TODO need new consts and params for v2 calls + EthCoinType::Eth => (Address::default(), self.gas_limit.eth_sender_refund), + EthCoinType::Erc20 { + platform: _, + token_addr, + } => (*token_addr, self.gas_limit.erc20_sender_refund), + EthCoinType::Nft { .. } => { + return Err(TransactionErr::ProtocolNotSupported(ERRL!( + "NFT protocol is not supported for ETH and ERC20 Swaps" + ))) + }, + }; + let taker_swap_v2_contract = self .swap_v2_contracts .as_ref() @@ -333,20 +351,7 @@ impl EthCoin { )); let maker_address = public_to_address(args.maker_pubkey); let payment_time_lock: u32 = try_tx_s!(args.payment_time_lock.try_into()); - let (token_address, gas_limit) = match &self.coin_type { - // TODO need new consts and params for v2 calls. now it uses v1 - EthCoinType::Eth => (Address::default(), self.gas_limit.eth_sender_refund), - EthCoinType::Erc20 { - platform: _, - token_addr, - // TODO need new consts and params for v2 calls. now it uses v1 - } => (*token_addr, self.gas_limit.erc20_sender_refund), - EthCoinType::Nft { .. } => { - return Err(TransactionErr::ProtocolNotSupported(ERRL!( - "NFT protocol is not supported for ETH and ERC20 Swaps" - ))) - }, - }; + let refund_args = TakerRefundSecretArgs { dex_fee, payment_amount, @@ -415,6 +420,16 @@ impl EthCoin { gen_args: &GenTakerPaymentSpendArgs<'_, Self>, secret: &[u8], ) -> Result { + // TODO need new consts and params for v2 calls + let gas_limit = match self.coin_type { + EthCoinType::Eth => U256::from(self.gas_limit.eth_receiver_spend), + EthCoinType::Erc20 { .. } => U256::from(self.gas_limit.erc20_receiver_spend), + EthCoinType::Nft { .. } => { + return Err(TransactionErr::ProtocolNotSupported(ERRL!( + "NFT protocol is not supported for ETH and ERC20 Swaps" + ))) + }, + }; let (taker_swap_v2_contract, approve_func, token_address) = self .taker_swap_v2_details(TAKER_PAYMENT_APPROVE, TAKER_PAYMENT_APPROVE) .await?; @@ -426,12 +441,7 @@ impl EthCoin { .await ) }; - // TODO need new consts and params for v2 calls - let gas_limit = match self.coin_type { - EthCoinType::Eth => U256::from(self.gas_limit.eth_receiver_spend), - EthCoinType::Erc20 { .. } => U256::from(self.gas_limit.erc20_receiver_spend), - EthCoinType::Nft { .. } => unreachable!(), // EthCoinType::Nft case was already checked in taker_swap_v2_details - }; + let payment_tx = self .sign_and_send_transaction(0.into(), Action::Call(taker_swap_v2_contract), data, gas_limit) .compat() diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 9502a88633..a08df0459d 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1479,7 +1479,10 @@ pub enum ValidateSwapV2TxError { Rpc(String), /// Serialized tx bytes don't match ones received from coin's RPC. #[display(fmt = "Tx bytes {:02x} don't match ones received from rpc {:02x}", actual, from_rpc)] - TxBytesMismatch { from_rpc: BytesJson, actual: BytesJson }, + TxBytesMismatch { + from_rpc: BytesJson, + actual: BytesJson, + }, /// Provided transaction doesn't have output with specific index TxLacksOfOutputs, /// Input payment timelock overflows the type used by specific coin. @@ -1493,6 +1496,7 @@ pub enum ValidateSwapV2TxError { TxDoesNotExist(String), /// Transaction has wrong properties, for example, it has been sent to a wrong address. WrongPaymentTx(String), + ProtocolNotSupported(String), } impl From for ValidateSwapV2TxError { diff --git a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs index 0f58bf68e7..458e3957ad 100644 --- a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs @@ -353,7 +353,8 @@ pub struct MakerSwapStateMachine Date: Mon, 12 Aug 2024 12:09:29 +0700 Subject: [PATCH 183/233] docker tests: add `search_for_taker_funding_spend` func in send_approve_and_spend tests --- mm2src/coins/eth.rs | 6 ++-- .../tests/docker_tests/eth_docker_tests.rs | 28 ++++++++++++++++++- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index f15d67e31a..b4531b76b1 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7138,12 +7138,12 @@ impl TakerCoinSwapOpsV2 for EthCoin { self.taker_payment_approve(args).await } - // TODO lets call refund_taker_funding_timelock inside this func? + // TODO lets reuse refund_taker_funding_timelock_impl inside this func? async fn refund_combined_taker_payment( &self, - _args: RefundTakerPaymentArgs<'_>, + args: RefundTakerPaymentArgs<'_>, ) -> Result { - todo!() + self.refund_taker_funding_timelock_impl(args).await } /// Eth doesnt have preimages diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 967d3e0a2f..2724318834 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -13,7 +13,7 @@ use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_reque EthPrivKeyBuildPolicy, SignedEthTx, SwapV2Contracts, ERC20_ABI}; use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, CommonSwapOpsV2, ConfirmPaymentInput, - DerivationMethod, DexFee, Eip1559Ops, FoundSwapTxSpend, GenTakerFundingSpendArgs, + DerivationMethod, DexFee, Eip1559Ops, FoundSwapTxSpend, FundingTxSpend, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, MakerNftSwapOpsV2, MarketCoinOps, MmCoinEnum, MmCoinStruct, NftSwapInfo, ParseCoinAssocTypes, ParseNftAssocTypes, PrivKeyBuildPolicy, RefundFundingSecretArgs, RefundNftMakerPaymentArgs, RefundPaymentArgs, RefundTakerPaymentArgs, SearchForSwapTxSpendInput, @@ -1953,6 +1953,19 @@ fn send_approve_and_spend_eth() { ); wait_for_confirmations(&taker_coin, &taker_approve_tx, 100); + wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); + let check_taker_approved_tx = block_on(maker_coin.search_for_taker_funding_spend(&taker_approve_tx, 0u64, &[])) + .unwrap() + .unwrap(); + match check_taker_approved_tx { + FundingTxSpend::TransferredToTakerPayment(tx) => { + assert_eq!(tx, taker_approve_tx); + }, + FundingTxSpend::RefundedTimelock(_) | FundingTxSpend::RefundedSecret { .. } => { + panic!("Wrong FundingTxSpend variant, expected TransferredToTakerPayment") + }, + }; + let dex_fee_pub = sepolia_taker_swap_v2(); let spend_args = GenTakerPaymentSpendArgs { taker_tx: &taker_approve_tx, @@ -2053,6 +2066,19 @@ fn send_approve_and_spend_erc20() { ); wait_for_confirmations(&taker_coin, &taker_approve_tx, 100); + wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); + let check_taker_approved_tx = block_on(maker_coin.search_for_taker_funding_spend(&taker_approve_tx, 0u64, &[])) + .unwrap() + .unwrap(); + match check_taker_approved_tx { + FundingTxSpend::TransferredToTakerPayment(tx) => { + assert_eq!(tx, taker_approve_tx); + }, + FundingTxSpend::RefundedTimelock(_) | FundingTxSpend::RefundedSecret { .. } => { + panic!("Wrong FundingTxSpend variant, expected TransferredToTakerPayment") + }, + }; + let dex_fee_pub = sepolia_taker_swap_v2(); let spend_args = GenTakerPaymentSpendArgs { taker_tx: &taker_approve_tx, From 046dc323c72999da8d35874e2934f9c81da3a1bf Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 12 Aug 2024 13:20:47 +0700 Subject: [PATCH 184/233] move coin_type match at the beginning in search_for_taker_funding_spend_impl --- mm2src/coins/eth/eth_swap_v2.rs | 14 +++++++------- .../tests/docker_tests/eth_docker_tests.rs | 2 ++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index c84527174f..7e87b56b8e 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -378,13 +378,6 @@ impl EthCoin { &self, tx: &SignedEthTx, ) -> Result>, SearchForFundingSpendErr> { - let taker_swap_v2_contract = self - .swap_v2_contracts - .as_ref() - .map(|contracts| contracts.taker_swap_v2_contract) - .ok_or_else(|| { - SearchForFundingSpendErr::Internal(ERRL!("Expected swap_v2_contracts to be Some, but found None")) - })?; let decoded = { let approve_func = match self.coin_type { EthCoinType::Eth | EthCoinType::Erc20 { .. } => TAKER_SWAP_V2 @@ -399,6 +392,13 @@ impl EthCoin { decode_contract_call(approve_func, tx.unsigned().data()) .map_err(|e| SearchForFundingSpendErr::Internal(ERRL!("Failed to decode tx data:{}", e)))? }; + let taker_swap_v2_contract = self + .swap_v2_contracts + .as_ref() + .map(|contracts| contracts.taker_swap_v2_contract) + .ok_or_else(|| { + SearchForFundingSpendErr::Internal(ERRL!("Expected swap_v2_contracts to be Some, but found None")) + })?; let taker_status = self .payment_status_v2( taker_swap_v2_contract, diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 2724318834..e6b40d6393 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1718,6 +1718,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { #[test] fn send_and_refund_taker_funding_by_secret_erc20() { + thread::sleep(Duration::from_secs(2)); let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); @@ -1749,6 +1750,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { swap_unique_data: &[], }; + thread::sleep(Duration::from_secs(4)); wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); From 303056fbf86b5bc0c068cd4204d4c78b112e6c1c Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 12 Aug 2024 14:28:52 +0700 Subject: [PATCH 185/233] more doc comments for swap v2 methods --- mm2src/coins/eth.rs | 14 ++++++++++---- mm2src/coins/eth/eth_swap_v2.rs | 3 ++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index b4531b76b1..92faea8324 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7074,11 +7074,13 @@ impl Eip1559Ops for EthCoin { #[async_trait] impl TakerCoinSwapOpsV2 for EthCoin { + /// Calls `"ethTakerPayment"` or `"erc20TakerPayment"` swap contract methods. + /// Returns taker sent payment transaction. async fn send_taker_funding(&self, args: SendTakerFundingArgs<'_>) -> Result { self.send_taker_funding_impl(args).await } - /// Validates sent taker payment + /// Validates taker payment transaction. async fn validate_taker_funding(&self, args: ValidateTakerFundingArgs<'_, Self>) -> ValidateSwapV2TxResult { self.validate_taker_funding_impl(args).await } @@ -7097,7 +7099,8 @@ impl TakerCoinSwapOpsV2 for EthCoin { self.refund_taker_funding_secret_impl(args).await } - /// Check if taker payment state is `TakerApproved` + /// Checks that taker payment state is `TakerApproved`. + /// Accepts taker approve payment transaction and returns it if the state is correct. async fn search_for_taker_funding_spend( &self, tx: &Self::Tx, @@ -7128,7 +7131,8 @@ impl TakerCoinSwapOpsV2 for EthCoin { Ok(()) } - /// Taker approves payment calling `takerPaymentApprove` for EVM based chains + /// Taker approves payment calling `takerPaymentApprove` for EVM based chains. + /// Function accepts taker payment transaction, returns taker approve payment transaction. async fn sign_and_send_taker_funding_spend( &self, _preimage: &TxPreimageWithSig, @@ -7167,7 +7171,8 @@ impl TakerCoinSwapOpsV2 for EthCoin { Ok(()) } - /// Taker swap contract `spendTakerPayment` method is called for EVM based chains + /// Taker swap contract `spendTakerPayment` method is called for EVM based chains. + /// Returns maker spent payment transaction. async fn sign_and_broadcast_taker_payment_spend( &self, _preimage: &TxPreimageWithSig, @@ -7178,6 +7183,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { self.sign_and_broadcast_taker_payment_spend_impl(gen_args, secret).await } + /// Checks that taker payment state is `MakerSpent`. Returns maker spent payment transaction. async fn wait_for_taker_payment_spend( &self, _taker_payment: &Self::Tx, diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 7e87b56b8e..2f7566d9ba 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -373,7 +373,8 @@ impl EthCoin { .await } - /// Check if taker payment state is `TakerApproved` + /// Checks that taker payment state is `TakerApproved`. + /// Accepts a taker-approved payment transaction and returns it if the state is correct. pub(crate) async fn search_for_taker_funding_spend_impl( &self, tx: &SignedEthTx, From bf70525221f171c81f03756c51cb50b0e44827e5 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 12 Aug 2024 18:29:37 +0700 Subject: [PATCH 186/233] wait_for_taker_payment_spend_impl WIP --- mm2src/coins/eth.rs | 9 +++++---- mm2src/coins/eth/eth_swap_v2.rs | 17 +++++++++++++---- .../tests/docker_tests/eth_docker_tests.rs | 3 +-- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 92faea8324..895c926004 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7183,14 +7183,15 @@ impl TakerCoinSwapOpsV2 for EthCoin { self.sign_and_broadcast_taker_payment_spend_impl(gen_args, secret).await } - /// Checks that taker payment state is `MakerSpent`. Returns maker spent payment transaction. + /// Checks that taker payment state is `MakerSpent`. + /// Accepts maker spent payment transaction and returns it if payment status is correct. async fn wait_for_taker_payment_spend( &self, - _taker_payment: &Self::Tx, + taker_payment: &Self::Tx, _from_block: u64, - _wait_until: u64, + wait_until: u64, ) -> MmResult { - todo!() + self.wait_for_taker_payment_spend_impl(taker_payment, wait_until).await } } diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 2f7566d9ba..99767532d7 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -2,14 +2,15 @@ use super::eth::{wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, TAKER_ use super::{decode_contract_call, get_function_input_data, ParseCoinAssocTypes, RefundFundingSecretArgs, RefundTakerPaymentArgs, SendTakerFundingArgs, SwapTxTypeWithSecretHash, TakerPaymentStateV2, Transaction, TransactionErr, ValidateSwapV2TxError, ValidateSwapV2TxResult, ValidateTakerFundingArgs}; -use crate::{FundingTxSpend, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, SearchForFundingSpendErr}; +use crate::{FundingTxSpend, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, SearchForFundingSpendErr, + WaitForTakerPaymentSpendError}; use enum_derives::EnumFromStringify; use ethabi::{Contract, Function, Token}; use ethcore_transaction::Action; use ethereum_types::{Address, Public, U256}; use ethkey::public_to_address; use futures::compat::Future01CompatExt; -use mm2_err_handle::prelude::{MapToMmResult, MmError}; +use mm2_err_handle::prelude::{MapToMmResult, MmError, MmResult}; use mm2_number::BigDecimal; use std::convert::TryInto; use std::num::TryFromIntError; @@ -443,11 +444,19 @@ impl EthCoin { ) }; - let payment_tx = self + let spend_payment_tx = self .sign_and_send_transaction(0.into(), Action::Call(taker_swap_v2_contract), data, gas_limit) .compat() .await?; - Ok(payment_tx) + Ok(spend_payment_tx) + } + + pub(crate) async fn wait_for_taker_payment_spend_impl( + &self, + _taker_payment: &SignedEthTx, + _wait_until: u64, + ) -> MmResult { + todo!() } /// Prepares data for EtomicSwapTakerV2 contract `ethTakerPayment` method diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index e6b40d6393..5bc16f2bda 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1718,7 +1718,6 @@ fn send_and_refund_taker_funding_by_secret_eth() { #[test] fn send_and_refund_taker_funding_by_secret_erc20() { - thread::sleep(Duration::from_secs(2)); let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); @@ -2106,7 +2105,7 @@ fn send_approve_and_spend_erc20() { #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { - thread::sleep(Duration::from_secs(50)); + thread::sleep(Duration::from_secs(55)); let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); From 0bae344289e12555df88b3b9969500491cce5887 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 13 Aug 2024 11:30:00 +0700 Subject: [PATCH 187/233] review: remove TakerRefundSecretArgs and reuse TakerRefundArgs --- mm2src/coins/eth/eth_swap_v2.rs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 99767532d7..1542f4d046 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -30,20 +30,11 @@ struct TakerFundingArgs { payment_time_lock: u32, } -struct TakerRefundSecretArgs { - dex_fee: U256, - payment_amount: U256, - maker_address: Address, - taker_secret: [u8; 32], - maker_secret_hash: [u8; 32], - payment_time_lock: u32, - token_address: Address, -} - struct TakerRefundArgs { dex_fee: U256, payment_amount: U256, maker_address: Address, + taker_secret: [u8; 32], taker_secret_hash: [u8; 32], maker_secret_hash: [u8; 32], payment_time_lock: u32, @@ -300,6 +291,7 @@ impl EthCoin { dex_fee, payment_amount, maker_address, + taker_secret: [0u8; 32], taker_secret_hash: try_tx_s!(taker_secret_hash.try_into()), maker_secret_hash: try_tx_s!(maker_secret_hash.try_into()), payment_time_lock, @@ -353,11 +345,12 @@ impl EthCoin { let maker_address = public_to_address(args.maker_pubkey); let payment_time_lock: u32 = try_tx_s!(args.payment_time_lock.try_into()); - let refund_args = TakerRefundSecretArgs { + let refund_args = TakerRefundArgs { dex_fee, payment_amount, maker_address, taker_secret, + taker_secret_hash: [0u8; 32], maker_secret_hash, payment_time_lock, token_address, @@ -552,7 +545,7 @@ impl EthCoin { /// address tokenAddress async fn prepare_taker_refund_payment_secret_data( &self, - args: &TakerRefundSecretArgs, + args: &TakerRefundArgs, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("refundTakerPaymentSecret")?; let id = self.etomic_swap_id(args.payment_time_lock, &args.maker_secret_hash); From e65f224bf278bc09c586c62adcb508c594c83eea Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 13 Aug 2024 12:27:34 +0700 Subject: [PATCH 188/233] review: use checked_add and InvalidData --- mm2src/coins/coin_errors.rs | 3 +++ mm2src/coins/eth/eth_swap_v2.rs | 12 ++++++++---- mm2src/coins/lp_coins.rs | 8 +++++--- mm2src/coins/utxo/utxo_common.rs | 2 +- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/mm2src/coins/coin_errors.rs b/mm2src/coins/coin_errors.rs index 28d4cd41ef..ae0f027019 100644 --- a/mm2src/coins/coin_errors.rs +++ b/mm2src/coins/coin_errors.rs @@ -51,6 +51,8 @@ pub enum ValidatePaymentError { TimelockOverflow(TryFromIntError), #[display(fmt = "Nft Protocol is not supported yet!")] NftProtocolNotSupported, + /// Got invalid data + InvalidData(String), } impl From for ValidatePaymentError { @@ -88,6 +90,7 @@ impl From for ValidatePaymentError { PaymentStatusErr::AbiError(e) | PaymentStatusErr::Internal(e) | PaymentStatusErr::TxDeserializationError(e) => Self::InternalError(e), + PaymentStatusErr::InvalidData(e) => Self::InvalidData(e), } } } diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 1542f4d046..4c8e7d1b27 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -149,11 +149,11 @@ impl EthCoin { let funding_time_lock: u32 = args .funding_time_lock .try_into() - .map_to_mm(|e: TryFromIntError| ValidateSwapV2TxError::LocktimeOverflow(e.to_string()))?; + .map_to_mm(|e: TryFromIntError| ValidateSwapV2TxError::Overflow(e.to_string()))?; let payment_time_lock: u32 = args .payment_time_lock .try_into() - .map_to_mm(|e: TryFromIntError| ValidateSwapV2TxError::LocktimeOverflow(e.to_string()))?; + .map_to_mm(|e: TryFromIntError| ValidateSwapV2TxError::Overflow(e.to_string()))?; let swap_id = self.etomic_swap_id(payment_time_lock, args.maker_secret_hash); let taker_status = self .payment_status_v2( @@ -656,7 +656,7 @@ impl EthCoin { })?; match state { Token::Uint(state) => Ok(*state), - _ => Err(PaymentStatusErr::Internal(ERRL!( + _ => Err(PaymentStatusErr::InvalidData(ERRL!( "Payment status must be Uint, got {:?}", state ))), @@ -790,7 +790,9 @@ fn validate_eth_taker_payment_data( ))); } } - let total = args.dex_fee + args.amount; + let total = args.amount.checked_add(args.dex_fee).ok_or_else(|| { + ValidateSwapV2TxError::Overflow("Overflow occurred while calculating total payment".to_string()) + })?; if total != tx_value { return MmError::err(ValidateSwapV2TxError::WrongPaymentTx(format!( "ETH Taker Payment amount, is invalid, expected {:?}, got {:?}", @@ -881,4 +883,6 @@ pub(crate) enum PaymentStatusErr { Internal(String), #[display(fmt = "Tx deserialization error: {}", _0)] TxDeserializationError(String), + #[display(fmt = "Invalid data error: {}", _0)] + InvalidData(String), } diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index a08df0459d..3e5f183965 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1485,8 +1485,8 @@ pub enum ValidateSwapV2TxError { }, /// Provided transaction doesn't have output with specific index TxLacksOfOutputs, - /// Input payment timelock overflows the type used by specific coin. - LocktimeOverflow(String), + /// Indicates that overflow occurred, either while calculating a total payment or converting the timelock. + Overflow(String), /// Internal error #[from_stringify("ethabi::Error")] Internal(String), @@ -1497,6 +1497,8 @@ pub enum ValidateSwapV2TxError { /// Transaction has wrong properties, for example, it has been sent to a wrong address. WrongPaymentTx(String), ProtocolNotSupported(String), + /// Got invalid data + InvalidData(String), } impl From for ValidateSwapV2TxError { @@ -1513,8 +1515,8 @@ impl From for ValidateSwapV2TxError { PaymentStatusErr::AbiError(e) | PaymentStatusErr::Internal(e) | PaymentStatusErr::TxDeserializationError(e) => ValidateSwapV2TxError::Internal(e), - PaymentStatusErr::Transport(e) => ValidateSwapV2TxError::Rpc(e), + PaymentStatusErr::InvalidData(e) => ValidateSwapV2TxError::InvalidData(e), } } } diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 2c1e412c04..06595be076 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -4888,7 +4888,7 @@ where let time_lock = args .funding_time_lock .try_into() - .map_to_mm(|e: TryFromIntError| ValidateSwapV2TxError::LocktimeOverflow(e.to_string()))?; + .map_to_mm(|e: TryFromIntError| ValidateSwapV2TxError::Overflow(e.to_string()))?; let redeem_script = swap_proto_v2_scripts::taker_funding_script( time_lock, From 46dcbc179af36b6acffad4c06c977132bc400852 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 13 Aug 2024 14:06:53 +0700 Subject: [PATCH 189/233] eth tpu v2: wait_for_taker_payment_spend_impl --- mm2src/coins/eth/eth_swap_v2.rs | 47 ++++++++++++++++++++++++++++++--- mm2src/coins/lp_coins.rs | 20 ++++++++++++-- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 4c8e7d1b27..93419a0dcb 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -4,6 +4,8 @@ use super::{decode_contract_call, get_function_input_data, ParseCoinAssocTypes, TransactionErr, ValidateSwapV2TxError, ValidateSwapV2TxResult, ValidateTakerFundingArgs}; use crate::{FundingTxSpend, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, SearchForFundingSpendErr, WaitForTakerPaymentSpendError}; +use common::executor::Timer; +use common::now_sec; use enum_derives::EnumFromStringify; use ethabi::{Contract, Function, Token}; use ethcore_transaction::Action; @@ -446,10 +448,48 @@ impl EthCoin { pub(crate) async fn wait_for_taker_payment_spend_impl( &self, - _taker_payment: &SignedEthTx, - _wait_until: u64, + taker_payment: &SignedEthTx, + wait_until: u64, ) -> MmResult { - todo!() + let decoded = { + let spend_func = match self.coin_type { + EthCoinType::Eth | EthCoinType::Erc20 { .. } => TAKER_SWAP_V2.function("spendTakerPayment")?, + EthCoinType::Nft { .. } => { + return MmError::err(WaitForTakerPaymentSpendError::Internal( + "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), + )); + }, + }; + decode_contract_call(spend_func, taker_payment.unsigned().data())? + }; + let taker_swap_v2_contract = self + .swap_v2_contracts + .as_ref() + .map(|contracts| contracts.taker_swap_v2_contract) + .ok_or_else(|| { + WaitForTakerPaymentSpendError::Internal( + "Expected swap_v2_contracts to be Some, but found None".to_string(), + ) + })?; + loop { + let taker_status = self + .payment_status_v2( + taker_swap_v2_contract, + decoded[0].clone(), // id from spendTakerPayment + &TAKER_SWAP_V2, + EthPaymentType::TakerPayments, + 3, + ) + .await?; + if taker_status == U256::from(TakerPaymentStateV2::MakerSpent as u8) { + return Ok(taker_payment.clone()); + } + let now = now_sec(); + if now > wait_until { + return MmError::err(WaitForTakerPaymentSpendError::Timeout { wait_until, now }); + } + Timer::sleep(10.).await; + } } /// Prepares data for EtomicSwapTakerV2 contract `ethTakerPayment` method @@ -690,7 +730,6 @@ impl EthCoin { } } -#[allow(dead_code)] #[derive(Debug, Display, EnumFromStringify)] pub(crate) enum PrepareTxDataError { #[from_stringify("ethabi::Error")] diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 3e5f183965..36cbf00391 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1843,7 +1843,7 @@ pub trait MakerNftSwapOpsV2: ParseCoinAssocTypes + ParseNftAssocTypes + Send + S } /// Enum representing errors that can occur while waiting for taker payment spend. -#[derive(Display)] +#[derive(Display, EnumFromStringify)] pub enum WaitForTakerPaymentSpendError { /// Timeout error variant, indicating that the wait for taker payment spend has timed out. #[display( @@ -1857,9 +1857,14 @@ pub enum WaitForTakerPaymentSpendError { /// The current timestamp when the timeout occurred. now: u64, }, - /// Invalid input transaction error variant, containing additional information about the error. InvalidInputTx(String), + Internal(String), + #[from_stringify("ethabi::Error")] + #[display(fmt = "Abi error: {}", _0)] + AbiError(String), + InvalidData(String), + Transport(String), } impl From for WaitForTakerPaymentSpendError { @@ -1875,6 +1880,17 @@ impl From for WaitForTakerPaymentSpendError { } } +impl From for WaitForTakerPaymentSpendError { + fn from(e: PaymentStatusErr) -> Self { + match e { + PaymentStatusErr::AbiError(e) => Self::AbiError(e), + PaymentStatusErr::Transport(e) => Self::Transport(e), + PaymentStatusErr::Internal(e) | PaymentStatusErr::TxDeserializationError(e) => Self::Internal(e), + PaymentStatusErr::InvalidData(e) => Self::InvalidData(e), + } + } +} + /// Enum representing different ways a funding transaction can be spent. /// /// This enum is generic over types that implement the `ParseCoinAssocTypes` trait. From 6c4814d7ec41b5057301b30cb3436f7b2382ae09 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 13 Aug 2024 14:08:52 +0700 Subject: [PATCH 190/233] move get script_pubkey from loop --- mm2src/coins/utxo/utxo_common.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 06595be076..d090522e41 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -2871,13 +2871,12 @@ pub async fn wait_for_output_spend_impl( wait_until: u64, check_every: f64, ) -> MmResult { + let script_pubkey = &tx + .outputs + .get(output_index) + .or_mm_err(|| WaitForOutputSpendErr::NoOutputWithIndex(output_index))? + .script_pubkey; loop { - let script_pubkey = &tx - .outputs - .get(output_index) - .or_mm_err(|| WaitForOutputSpendErr::NoOutputWithIndex(output_index))? - .script_pubkey; - match coin .rpc_client .find_output_spend( From 3bf653e1df5da542cab593999b44facfcbcd6acb Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 13 Aug 2024 14:23:44 +0700 Subject: [PATCH 191/233] add wait_for_taker_payment_spend to eth tests --- mm2src/coins/lp_coins.rs | 2 +- .../mm2_main/tests/docker_tests/eth_docker_tests.rs | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 36cbf00391..34be7e87e5 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1843,7 +1843,7 @@ pub trait MakerNftSwapOpsV2: ParseCoinAssocTypes + ParseNftAssocTypes + Send + S } /// Enum representing errors that can occur while waiting for taker payment spend. -#[derive(Display, EnumFromStringify)] +#[derive(Display, Debug, EnumFromStringify)] pub enum WaitForTakerPaymentSpendError { /// Timeout error variant, indicating that the wait for taker payment spend has timed out. #[display( diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 5bc16f2bda..98916e9e72 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1813,7 +1813,6 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { // if TakerPaymentState is `PaymentSent` then timestamp should exceed payment pre-approve lock time (funding_time_lock) let funding_time_lock = now_sec() - 3000; - // TODO need to impl taker approve to test exceeded payment_time_lock let payment_time_lock = now_sec() + 1000; let dex_fee = &DexFee::Standard("0.00001".into()); @@ -1890,7 +1889,7 @@ fn send_approve_and_spend_eth() { let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); let funding_time_lock = now_sec() + 3000; - let payment_time_lock = now_sec() + 1000; + let payment_time_lock = now_sec() + 600; let taker_address = block_on(taker_coin.my_addr()); let maker_address = block_on(maker_coin.my_addr()); @@ -1986,8 +1985,7 @@ fn send_approve_and_spend_eth() { .unwrap(); log!("Maker spent ETH payment, tx hash: {:02x}", spend_tx.tx_hash()); wait_for_confirmations(&maker_coin, &spend_tx, 100); - - // TODO add wait_for_taker_payment_spend when it will be implemented + block_on(taker_coin.wait_for_taker_payment_spend(&spend_tx, 0u64, payment_time_lock)).unwrap(); } #[test] @@ -2003,7 +2001,7 @@ fn send_approve_and_spend_erc20() { let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); let funding_time_lock = now_sec() + 3000; - let payment_time_lock = now_sec() + 1000; + let payment_time_lock = now_sec() + 600; let taker_address = block_on(taker_coin.my_addr()); let maker_address = block_on(maker_coin.my_addr()); @@ -2098,9 +2096,7 @@ fn send_approve_and_spend_erc20() { block_on(maker_coin.sign_and_broadcast_taker_payment_spend(&preimage, &spend_args, &maker_secret, &[])) .unwrap(); log!("Maker spent ERC20 payment, tx hash: {:02x}", spend_tx.tx_hash()); - wait_for_confirmations(&maker_coin, &spend_tx, 100); - - // TODO add wait_for_taker_payment_spend when it will be implemented + block_on(taker_coin.wait_for_taker_payment_spend(&spend_tx, 0u64, payment_time_lock)).unwrap(); } #[test] From 74d31ca9aa0d281fc15565cf5a96bcaf8b53c9ab Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 13 Aug 2024 14:52:07 +0700 Subject: [PATCH 192/233] change sleep duration in send_and_refund_taker_funding_exceed, remove validate func from them --- .../tests/docker_tests/eth_docker_tests.rs | 76 +------------------ 1 file changed, 4 insertions(+), 72 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 98916e9e72..1a8556579a 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1809,7 +1809,6 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { let maker_secret_hash = sha256(&maker_secret).to_vec(); let taker_address = block_on(taker_coin.my_addr()); - let maker_address = block_on(maker_coin.my_addr()); // if TakerPaymentState is `PaymentSent` then timestamp should exceed payment pre-approve lock time (funding_time_lock) let funding_time_lock = now_sec() - 3000; @@ -1835,22 +1834,6 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); wait_for_confirmations(&taker_coin, &funding_tx, 100); - let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); - let validate = ValidateTakerFundingArgs { - funding_tx: &funding_tx, - funding_time_lock, - payment_time_lock, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - taker_pub, - dex_fee, - premium_amount: Default::default(), - trading_amount: trading_amount.clone(), - swap_unique_data: &[], - }; - wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); - block_on(maker_coin.validate_taker_funding(validate)).unwrap(); - let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash: &maker_secret_hash, taker_secret_hash: &taker_secret_hash, @@ -2101,7 +2084,7 @@ fn send_approve_and_spend_erc20() { #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { - thread::sleep(Duration::from_secs(55)); + thread::sleep(Duration::from_secs(60)); let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); @@ -2112,7 +2095,6 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { let maker_secret_hash = sha256(&maker_secret).to_vec(); let taker_address = block_on(taker_coin.my_addr()); - let maker_address = block_on(maker_coin.my_addr()); // if TakerPaymentState is `PaymentSent` then timestamp should exceed payment pre-approve lock time (funding_time_lock) let funding_time_lock = now_sec() + 29; @@ -2136,26 +2118,9 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 100); thread::sleep(Duration::from_secs(30)); - let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); - let validate = ValidateTakerFundingArgs { - funding_tx: &funding_tx, - funding_time_lock, - payment_time_lock, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - taker_pub, - dex_fee, - premium_amount: Default::default(), - trading_amount: trading_amount.clone(), - swap_unique_data: &[], - }; - wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); - block_on(maker_coin.validate_taker_funding(validate)).unwrap(); - let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash: &maker_secret_hash, taker_secret_hash: &taker_secret_hash, @@ -2197,7 +2162,6 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_eth() { let payment_time_lock = now_sec() - 1000; let taker_address = block_on(taker_coin.my_addr()); - let maker_address = block_on(maker_coin.my_addr()); let dex_fee = &DexFee::Standard("0.00001".into()); let trading_amount = BigDecimal::from_str("0.0001").unwrap(); @@ -2220,21 +2184,6 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_eth() { wait_for_confirmations(&taker_coin, &funding_tx, 100); let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); - let validate = ValidateTakerFundingArgs { - funding_tx: &funding_tx, - funding_time_lock, - payment_time_lock, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - taker_pub, - dex_fee, - premium_amount: Default::default(), - trading_amount: trading_amount.clone(), - swap_unique_data: &[], - }; - wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); - block_on(maker_coin.validate_taker_funding(validate)).unwrap(); - let approve_args = GenTakerFundingSpendArgs { funding_tx: &funding_tx, maker_pub, @@ -2284,7 +2233,7 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_eth() { #[test] fn send_and_refund_taker_funding_exceed_payment_timelock_erc20() { // sepolia test - thread::sleep(Duration::from_secs(32)); + thread::sleep(Duration::from_secs(28)); let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, erc20_conf, true); @@ -2294,10 +2243,9 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_erc20() { let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); let funding_time_lock = now_sec() + 29; - let payment_time_lock = now_sec() + 10; + let payment_time_lock = now_sec() + 15; let taker_address = block_on(taker_coin.my_addr()); - let maker_address = block_on(maker_coin.my_addr()); let dex_fee = &DexFee::Standard("0.00001".into()); let trading_amount = BigDecimal::from_str("0.0001").unwrap(); @@ -2317,26 +2265,10 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_erc20() { wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 100); - thread::sleep(Duration::from_secs(30)); + thread::sleep(Duration::from_secs(16)); let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); - let validate = ValidateTakerFundingArgs { - funding_tx: &funding_tx, - funding_time_lock, - payment_time_lock, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - taker_pub, - dex_fee, - premium_amount: Default::default(), - trading_amount: trading_amount.clone(), - swap_unique_data: &[], - }; - wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); - block_on(maker_coin.validate_taker_funding(validate)).unwrap(); - let approve_args = GenTakerFundingSpendArgs { funding_tx: &funding_tx, maker_pub, From 8a5d5df1426fb37c027f01ea43d0c2339d0f38c2 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 14 Aug 2024 10:12:14 +0700 Subject: [PATCH 193/233] provide get_decoded_and_swap_contract func to reduce code duplication --- mm2src/coins/eth/eth_swap_v2.rs | 79 +++++++++++++++------------------ mm2src/coins/lp_coins.rs | 9 ++++ 2 files changed, 45 insertions(+), 43 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 93419a0dcb..c62eff6d0d 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -375,27 +375,10 @@ impl EthCoin { &self, tx: &SignedEthTx, ) -> Result>, SearchForFundingSpendErr> { - let decoded = { - let approve_func = match self.coin_type { - EthCoinType::Eth | EthCoinType::Erc20 { .. } => TAKER_SWAP_V2 - .function(TAKER_PAYMENT_APPROVE) - .map_err(|e| SearchForFundingSpendErr::Internal(ERRL!("{}", e)))?, - EthCoinType::Nft { .. } => { - return Err(SearchForFundingSpendErr::Internal(ERRL!( - "NFT protocol is not supported for ETH and ERC20 Swaps" - ))) - }, - }; - decode_contract_call(approve_func, tx.unsigned().data()) - .map_err(|e| SearchForFundingSpendErr::Internal(ERRL!("Failed to decode tx data:{}", e)))? - }; - let taker_swap_v2_contract = self - .swap_v2_contracts - .as_ref() - .map(|contracts| contracts.taker_swap_v2_contract) - .ok_or_else(|| { - SearchForFundingSpendErr::Internal(ERRL!("Expected swap_v2_contracts to be Some, but found None")) - })?; + let (decoded, taker_swap_v2_contract) = self + .get_decoded_and_swap_contract(tx, TAKER_PAYMENT_APPROVE) + .await + .map_err(|e| SearchForFundingSpendErr::Internal(ERRL!("{}", e)))?; let taker_status = self .payment_status_v2( taker_swap_v2_contract, @@ -451,26 +434,9 @@ impl EthCoin { taker_payment: &SignedEthTx, wait_until: u64, ) -> MmResult { - let decoded = { - let spend_func = match self.coin_type { - EthCoinType::Eth | EthCoinType::Erc20 { .. } => TAKER_SWAP_V2.function("spendTakerPayment")?, - EthCoinType::Nft { .. } => { - return MmError::err(WaitForTakerPaymentSpendError::Internal( - "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), - )); - }, - }; - decode_contract_call(spend_func, taker_payment.unsigned().data())? - }; - let taker_swap_v2_contract = self - .swap_v2_contracts - .as_ref() - .map(|contracts| contracts.taker_swap_v2_contract) - .ok_or_else(|| { - WaitForTakerPaymentSpendError::Internal( - "Expected swap_v2_contracts to be Some, but found None".to_string(), - ) - })?; + let (decoded, taker_swap_v2_contract) = self + .get_decoded_and_swap_contract(taker_payment, "spendTakerPayment") + .await?; loop { let taker_status = self .payment_status_v2( @@ -689,14 +655,14 @@ impl EthCoin { let decoded_tokens = function.decode_output(&bytes.0)?; let state = decoded_tokens.get(state_index).ok_or_else(|| { - PaymentStatusErr::Internal(ERRL!( + PaymentStatusErr::Internal(format!( "Payment status must contain 'state' as the {} token", state_index )) })?; match state { Token::Uint(state) => Ok(*state), - _ => Err(PaymentStatusErr::InvalidData(ERRL!( + _ => Err(PaymentStatusErr::InvalidData(format!( "Payment status must be Uint, got {:?}", state ))), @@ -728,6 +694,33 @@ impl EthCoin { }; Ok((taker_swap_v2_contract, func, token_address)) } + + async fn get_decoded_and_swap_contract( + &self, + tx: &SignedEthTx, + function_name: &str, + ) -> Result<(Vec, Address), PrepareTxDataError> { + let decoded = { + let func = match self.coin_type { + EthCoinType::Eth | EthCoinType::Erc20 { .. } => TAKER_SWAP_V2.function(function_name)?, + EthCoinType::Nft { .. } => { + return Err(PrepareTxDataError::Internal( + "NFT protocol is not supported for ETH and ERC20 Swaps".to_string(), + )); + }, + }; + decode_contract_call(func, tx.unsigned().data())? + }; + let taker_swap_v2_contract = self + .swap_v2_contracts + .as_ref() + .map(|contracts| contracts.taker_swap_v2_contract) + .ok_or_else(|| { + PrepareTxDataError::Internal("Expected swap_v2_contracts to be Some, but found None".to_string()) + })?; + + Ok((decoded, taker_swap_v2_contract)) + } } #[derive(Debug, Display, EnumFromStringify)] diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 34be7e87e5..0d6b37672a 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1891,6 +1891,15 @@ impl From for WaitForTakerPaymentSpendError { } } +impl From for WaitForTakerPaymentSpendError { + fn from(e: PrepareTxDataError) -> Self { + match e { + PrepareTxDataError::AbiError(e) => Self::AbiError(e), + PrepareTxDataError::Internal(e) => Self::Internal(e), + } + } +} + /// Enum representing different ways a funding transaction can be spent. /// /// This enum is generic over types that implement the `ParseCoinAssocTypes` trait. From a72247ff44a97a35c2dbfa745d614bbee2bdd5e7 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 14 Aug 2024 10:15:01 +0700 Subject: [PATCH 194/233] move match coin_type to the beginning of fn taker_swap_v2_details --- mm2src/coins/eth/eth_swap_v2.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index c62eff6d0d..60d409276b 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -678,11 +678,6 @@ impl EthCoin { eth_func_name: &str, erc20_func_name: &str, ) -> Result<(Address, &Function, Address), TransactionErr> { - let taker_swap_v2_contract = self - .swap_v2_contracts - .as_ref() - .map(|contracts| contracts.taker_swap_v2_contract) - .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; let (func, token_address) = match self.coin_type { EthCoinType::Eth => (try_tx_s!(TAKER_SWAP_V2.function(eth_func_name)), Address::default()), EthCoinType::Erc20 { token_addr, .. } => (try_tx_s!(TAKER_SWAP_V2.function(erc20_func_name)), token_addr), @@ -692,6 +687,11 @@ impl EthCoin { ))) }, }; + let taker_swap_v2_contract = self + .swap_v2_contracts + .as_ref() + .map(|contracts| contracts.taker_swap_v2_contract) + .ok_or_else(|| TransactionErr::Plain(ERRL!("Expected swap_v2_contracts to be Some, but found None")))?; Ok((taker_swap_v2_contract, func, token_address)) } From 78166b1ac531dc0b66f30ea608d9a0301d0c0d73 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 14 Aug 2024 11:23:36 +0700 Subject: [PATCH 195/233] review: fn set_chain_id, remove redundant doc comms, update ABIError --- mm2src/coins/coin_errors.rs | 3 +-- mm2src/coins/eth/eth_swap_v2.rs | 8 ++++---- mm2src/coins/eth/nft_swap_v2/errors.rs | 5 +++-- mm2src/coins/eth/nft_swap_v2/mod.rs | 2 +- mm2src/coins/lp_coins.rs | 15 ++++++--------- mm2src/coins/qrc20.rs | 4 ++-- mm2src/coins/utxo/qtum_delegation.rs | 6 +++--- mm2src/mm2_test_helpers/src/for_tests.rs | 20 ++++++++++++-------- 8 files changed, 32 insertions(+), 31 deletions(-) diff --git a/mm2src/coins/coin_errors.rs b/mm2src/coins/coin_errors.rs index ae0f027019..72d66ec2bd 100644 --- a/mm2src/coins/coin_errors.rs +++ b/mm2src/coins/coin_errors.rs @@ -51,7 +51,6 @@ pub enum ValidatePaymentError { TimelockOverflow(TryFromIntError), #[display(fmt = "Nft Protocol is not supported yet!")] NftProtocolNotSupported, - /// Got invalid data InvalidData(String), } @@ -87,7 +86,7 @@ impl From for ValidatePaymentError { fn from(err: PaymentStatusErr) -> Self { match err { PaymentStatusErr::Transport(e) => Self::Transport(e), - PaymentStatusErr::AbiError(e) + PaymentStatusErr::ABIError(e) | PaymentStatusErr::Internal(e) | PaymentStatusErr::TxDeserializationError(e) => Self::InternalError(e), PaymentStatusErr::InvalidData(e) => Self::InvalidData(e), diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 60d409276b..bf444a22d1 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -726,8 +726,8 @@ impl EthCoin { #[derive(Debug, Display, EnumFromStringify)] pub(crate) enum PrepareTxDataError { #[from_stringify("ethabi::Error")] - #[display(fmt = "Abi error: {}", _0)] - AbiError(String), + #[display(fmt = "ABI error: {}", _0)] + ABIError(String), #[display(fmt = "Internal error: {}", _0)] Internal(String), } @@ -906,8 +906,8 @@ impl EthPaymentType { #[derive(Debug, Display, EnumFromStringify)] pub(crate) enum PaymentStatusErr { #[from_stringify("ethabi::Error")] - #[display(fmt = "Abi error: {}", _0)] - AbiError(String), + #[display(fmt = "ABI error: {}", _0)] + ABIError(String), #[from_stringify("web3::Error")] #[display(fmt = "Transport error: {}", _0)] Transport(String), diff --git a/mm2src/coins/eth/nft_swap_v2/errors.rs b/mm2src/coins/eth/nft_swap_v2/errors.rs index 3d966cfe02..0cbc881ff3 100644 --- a/mm2src/coins/eth/nft_swap_v2/errors.rs +++ b/mm2src/coins/eth/nft_swap_v2/errors.rs @@ -2,7 +2,8 @@ pub(crate) use crate::eth::eth_swap_v2::PrepareTxDataError; #[derive(Debug, Display)] pub(crate) enum Erc721FunctionError { - AbiError(String), + #[display(fmt = "ABI error: {}", _0)] + ABIError(String), FunctionNotFound(String), } @@ -15,7 +16,7 @@ pub(crate) enum HtlcParamsError { impl From for PrepareTxDataError { fn from(e: Erc721FunctionError) -> Self { match e { - Erc721FunctionError::AbiError(e) => PrepareTxDataError::AbiError(e), + Erc721FunctionError::ABIError(e) => PrepareTxDataError::ABIError(e), Erc721FunctionError::FunctionNotFound(e) => PrepareTxDataError::Internal(e), } } diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index 1c707d9b6e..2497c3737e 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -601,7 +601,7 @@ pub(crate) fn get_decoded_tx_data_and_bytes_index( fn erc721_transfer_with_data<'a>() -> Result<&'a ethabi::Function, Erc721FunctionError> { let functions = ERC721_CONTRACT .functions_by_name("safeTransferFrom") - .map_err(|e| Erc721FunctionError::AbiError(ERRL!("{}", e)))?; + .map_err(|e| Erc721FunctionError::ABIError(ERRL!("{}", e)))?; // Find the correct function variant by inspecting the input parameters. let function = functions diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 0d6b37672a..aabd8cfca3 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -998,7 +998,6 @@ pub struct RefundTakerPaymentArgs<'a> { pub tx_type_with_secret_hash: SwapTxTypeWithSecretHash<'a>, pub swap_unique_data: &'a [u8], pub watcher_reward: bool, - /// DEX fee pub dex_fee: &'a DexFee, /// Additional reward for maker (premium) pub premium_amount: BigDecimal, @@ -1345,7 +1344,6 @@ pub struct RefundFundingSecretArgs<'a, Coin: ParseCoinAssocTypes + ?Sized> { pub taker_secret: &'a [u8], pub taker_secret_hash: &'a [u8], pub maker_secret_hash: &'a [u8], - /// DEX fee pub dex_fee: &'a DexFee, /// Additional reward for maker (premium) pub premium_amount: BigDecimal, @@ -1497,7 +1495,6 @@ pub enum ValidateSwapV2TxError { /// Transaction has wrong properties, for example, it has been sent to a wrong address. WrongPaymentTx(String), ProtocolNotSupported(String), - /// Got invalid data InvalidData(String), } @@ -1512,7 +1509,7 @@ impl From for ValidateSwapV2TxError { impl From for ValidateSwapV2TxError { fn from(err: PaymentStatusErr) -> Self { match err { - PaymentStatusErr::AbiError(e) + PaymentStatusErr::ABIError(e) | PaymentStatusErr::Internal(e) | PaymentStatusErr::TxDeserializationError(e) => ValidateSwapV2TxError::Internal(e), PaymentStatusErr::Transport(e) => ValidateSwapV2TxError::Rpc(e), @@ -1533,7 +1530,7 @@ impl From for ValidateSwapV2TxError { impl From for ValidateSwapV2TxError { fn from(err: PrepareTxDataError) -> Self { match err { - PrepareTxDataError::AbiError(e) | PrepareTxDataError::Internal(e) => ValidateSwapV2TxError::Internal(e), + PrepareTxDataError::ABIError(e) | PrepareTxDataError::Internal(e) => ValidateSwapV2TxError::Internal(e), } } } @@ -1861,8 +1858,8 @@ pub enum WaitForTakerPaymentSpendError { InvalidInputTx(String), Internal(String), #[from_stringify("ethabi::Error")] - #[display(fmt = "Abi error: {}", _0)] - AbiError(String), + #[display(fmt = "ABI error: {}", _0)] + ABIError(String), InvalidData(String), Transport(String), } @@ -1883,7 +1880,7 @@ impl From for WaitForTakerPaymentSpendError { impl From for WaitForTakerPaymentSpendError { fn from(e: PaymentStatusErr) -> Self { match e { - PaymentStatusErr::AbiError(e) => Self::AbiError(e), + PaymentStatusErr::ABIError(e) => Self::ABIError(e), PaymentStatusErr::Transport(e) => Self::Transport(e), PaymentStatusErr::Internal(e) | PaymentStatusErr::TxDeserializationError(e) => Self::Internal(e), PaymentStatusErr::InvalidData(e) => Self::InvalidData(e), @@ -1894,7 +1891,7 @@ impl From for WaitForTakerPaymentSpendError { impl From for WaitForTakerPaymentSpendError { fn from(e: PrepareTxDataError) -> Self { match e { - PrepareTxDataError::AbiError(e) => Self::AbiError(e), + PrepareTxDataError::ABIError(e) => Self::ABIError(e), PrepareTxDataError::Internal(e) => Self::Internal(e), } } diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 3ee9e7761b..b1d250c755 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -452,11 +452,11 @@ pub enum Qrc20AbiError { #[display(fmt = "Invalid QRC20 ABI params: {}", _0)] InvalidParams(String), #[display(fmt = "QRC20 ABI error: {}", _0)] - AbiError(String), + ABIError(String), } impl From for Qrc20AbiError { - fn from(e: ethabi::Error) -> Qrc20AbiError { Qrc20AbiError::AbiError(e.to_string()) } + fn from(e: ethabi::Error) -> Qrc20AbiError { Qrc20AbiError::ABIError(e.to_string()) } } impl From for ValidatePaymentError { diff --git a/mm2src/coins/utxo/qtum_delegation.rs b/mm2src/coins/utxo/qtum_delegation.rs index ad9aec86e1..f7573fafbf 100644 --- a/mm2src/coins/utxo/qtum_delegation.rs +++ b/mm2src/coins/utxo/qtum_delegation.rs @@ -45,7 +45,7 @@ pub enum QtumStakingAbiError { #[display(fmt = "Invalid QRC20 ABI params: {}", _0)] InvalidParams(String), #[display(fmt = "QRC20 ABI error: {}", _0)] - AbiError(String), + ABIError(String), #[display(fmt = "Qtum POD error: {}", _0)] PodSigningError(String), #[display(fmt = "Internal error: {}", _0)] @@ -56,7 +56,7 @@ impl From for QtumStakingAbiError { fn from(e: Qrc20AbiError) -> Self { match e { Qrc20AbiError::InvalidParams(e) => QtumStakingAbiError::InvalidParams(e), - Qrc20AbiError::AbiError(e) => QtumStakingAbiError::AbiError(e), + Qrc20AbiError::ABIError(e) => QtumStakingAbiError::ABIError(e), } } } @@ -66,7 +66,7 @@ impl From for DelegationError { } impl From for QtumStakingAbiError { - fn from(e: ethabi::Error) -> QtumStakingAbiError { QtumStakingAbiError::AbiError(e.to_string()) } + fn from(e: ethabi::Error) -> QtumStakingAbiError { QtumStakingAbiError::ABIError(e.to_string()) } } impl From for DelegationError { diff --git a/mm2src/mm2_test_helpers/src/for_tests.rs b/mm2src/mm2_test_helpers/src/for_tests.rs index e4049a10bc..c52c52f6a7 100644 --- a/mm2src/mm2_test_helpers/src/for_tests.rs +++ b/mm2src/mm2_test_helpers/src/for_tests.rs @@ -831,7 +831,7 @@ pub fn erc20_dev_conf(contract_address: &str) -> Json { /// ERC20 token configuration used for dockerized tests on Sepolia pub fn sepolia_erc20_dev_conf(contract_address: &str) -> Json { let mut conf = erc20_dev_conf(contract_address); - conf["chain_id"] = json!(11155111); + set_chain_id(&mut conf, ETH_SEPOLIA_CHAIN_ID); conf } @@ -856,16 +856,20 @@ pub fn nft_dev_conf() -> Json { /// global NFT configuration used for Sepolia testnet pub fn nft_sepolia_conf() -> Json { let mut conf = nft_dev_conf(); - conf["chain_id"] = json!(11155111); + set_chain_id(&mut conf, ETH_SEPOLIA_CHAIN_ID); conf } +fn set_chain_id(conf: &mut Json, chain_id: u64) { + conf["chain_id"] = json!(chain_id); +} + pub fn eth_sepolia_conf() -> Json { json!({ "coin": "ETH", "name": "ethereum", "derivation_path": "m/44'/60'", - "chain_id": 11155111, + "chain_id": ETH_SEPOLIA_CHAIN_ID, "protocol": { "type": "ETH" }, @@ -879,7 +883,7 @@ pub fn eth_sepolia_trezor_firmware_compat_conf() -> Json { "coin": "tETH", "name": "ethereum", "derivation_path": "m/44'/1'", // Note: trezor uses coin type 1' for eth for testnet (SLIP44_TESTNET) - "chain_id": 11155111, + "chain_id": ETH_SEPOLIA_CHAIN_ID, "protocol": { "type": "ETH" }, @@ -909,12 +913,12 @@ pub fn jst_sepolia_conf() -> Json { json!({ "coin": "JST", "name": "jst", - "chain_id": 11155111, + "chain_id": ETH_SEPOLIA_CHAIN_ID, "protocol": { "type": "ERC20", "protocol_data": { "platform": "ETH", - "chain_id": 11155111, + "chain_id": ETH_SEPOLIA_CHAIN_ID, "contract_address": ETH_SEPOLIA_TOKEN_CONTRACT } }, @@ -926,14 +930,14 @@ pub fn jst_sepolia_trezor_conf() -> Json { json!({ "coin": "tJST", "name": "tjst", - "chain_id": 11155111, + "chain_id": ETH_SEPOLIA_CHAIN_ID, "derivation_path": "m/44'/1'", // Note: Trezor uses 1' coin type for all testnets "trezor_coin": "tETH", "protocol": { "type": "ERC20", "protocol_data": { "platform": "ETH", - "chain_id": 11155111, + "chain_id": ETH_SEPOLIA_CHAIN_ID, "contract_address": ETH_SEPOLIA_TOKEN_CONTRACT } } From 3629f0e9f4737d390f2027e3d2dc3261c79dd64a Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 14 Aug 2024 13:08:16 +0700 Subject: [PATCH 196/233] add doc comms, update sleep duration for send_and_refund_taker_funding_by_secret_erc20 and send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20 --- mm2src/coins/eth/eth_swap_v2.rs | 8 ++++ .../tests/docker_tests/eth_docker_tests.rs | 48 ++----------------- 2 files changed, 13 insertions(+), 43 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index bf444a22d1..1089d409f7 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -44,6 +44,8 @@ struct TakerRefundArgs { } impl EthCoin { + /// Calls `"ethTakerPayment"` or `"erc20TakerPayment"` swap contract methods. + /// Returns taker sent payment transaction. pub(crate) async fn send_taker_funding_impl( &self, args: SendTakerFundingArgs<'_>, @@ -212,6 +214,8 @@ impl EthCoin { Ok(()) } + /// Taker approves payment calling `takerPaymentApprove` for EVM based chains. + /// Function accepts taker payment transaction, returns taker approve payment transaction. pub(crate) async fn taker_payment_approve( &self, args: &GenTakerFundingSpendArgs<'_, Self>, @@ -395,6 +399,8 @@ impl EthCoin { Ok(None) } + /// Taker swap contract `spendTakerPayment` method is called for EVM based chains. + /// Returns maker spent payment transaction. pub(crate) async fn sign_and_broadcast_taker_payment_spend_impl( &self, gen_args: &GenTakerPaymentSpendArgs<'_, Self>, @@ -429,6 +435,8 @@ impl EthCoin { Ok(spend_payment_tx) } + /// Checks that taker payment state is `MakerSpent`. + /// Accepts maker spent payment transaction and returns it if payment status is correct. pub(crate) async fn wait_for_taker_payment_spend_impl( &self, taker_payment: &SignedEthTx, diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 1a8556579a..50b8a354b7 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1651,7 +1651,6 @@ fn send_and_refund_taker_funding_by_secret_eth() { let payment_time_lock = now_sec() + 1000; let taker_address = block_on(taker_coin.my_addr()); - let maker_address = block_on(maker_coin.my_addr()); let dex_fee = &DexFee::Standard("0.00001".into()); let trading_amount = BigDecimal::from_str("0.0001").unwrap(); @@ -1674,24 +1673,6 @@ fn send_and_refund_taker_funding_by_secret_eth() { let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 100); - - let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); - let validate = ValidateTakerFundingArgs { - funding_tx: &funding_tx, - funding_time_lock, - payment_time_lock, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - taker_pub, - dex_fee, - premium_amount: Default::default(), - trading_amount: trading_amount.clone(), - swap_unique_data: &[], - }; - wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); - block_on(maker_coin.validate_taker_funding(validate)).unwrap(); - let refund_args = RefundFundingSecretArgs { funding_tx: &funding_tx, funding_time_lock, @@ -1728,7 +1709,6 @@ fn send_and_refund_taker_funding_by_secret_erc20() { let maker_secret_hash = sha256(&maker_secret).to_vec(); let taker_address = block_on(taker_coin.my_addr()); - let maker_address = block_on(maker_coin.my_addr()); let funding_time_lock = now_sec() + 3000; let payment_time_lock = now_sec() + 1000; @@ -1753,24 +1733,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); - - wait_for_confirmations(&taker_coin, &funding_tx, 100); - - let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); - let validate = ValidateTakerFundingArgs { - funding_tx: &funding_tx, - funding_time_lock, - payment_time_lock, - taker_secret_hash: &taker_secret_hash, - maker_secret_hash: &maker_secret_hash, - taker_pub, - dex_fee, - premium_amount: Default::default(), - trading_amount: trading_amount.clone(), - swap_unique_data: &[], - }; - wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); - block_on(maker_coin.validate_taker_funding(validate)).unwrap(); + wait_for_confirmations(&taker_coin, &funding_tx, 150); let refund_args = RefundFundingSecretArgs { funding_tx: &funding_tx, @@ -1787,13 +1750,12 @@ fn send_and_refund_taker_funding_by_secret_erc20() { watcher_reward: false, }; wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); - thread::sleep(Duration::from_secs(1)); let funding_tx_refund = block_on(taker_coin.refund_taker_funding_secret(refund_args)).unwrap(); log!( "Taker refunded ERC20 funding by secret, tx hash: {:02x}", funding_tx_refund.tx_hash() ); - wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); + wait_for_confirmations(&taker_coin, &funding_tx_refund, 150); } #[test] @@ -2118,8 +2080,8 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 100); - thread::sleep(Duration::from_secs(30)); + wait_for_confirmations(&taker_coin, &funding_tx, 150); + thread::sleep(Duration::from_secs(29)); let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash: &maker_secret_hash, @@ -2144,7 +2106,7 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { "Taker refunded ERC20 funding after pre-approval lock time was exceeded, tx hash: {:02x}", funding_tx_refund.tx_hash() ); - wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); + wait_for_confirmations(&taker_coin, &funding_tx_refund, 150); } #[test] From f6ffcf1bc90a5ad2e5da720a5435331047390806 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 14 Aug 2024 17:06:52 +0700 Subject: [PATCH 197/233] review: reduce sleep time, use explicit U256::from --- mm2src/coins/eth/eth_swap_v2.rs | 12 ++++++------ .../mm2_main/tests/docker_tests/eth_docker_tests.rs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 1089d409f7..3e51d0f690 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -116,7 +116,7 @@ impl EthCoin { })?; } self.sign_and_send_transaction( - 0.into(), + U256::from(0), Action::Call(taker_swap_v2_contract), data, // TODO need new consts and params for v2 calls. now it uses v1 @@ -242,7 +242,7 @@ impl EthCoin { ) }; let approve_tx = self - .sign_and_send_transaction(0.into(), Action::Call(taker_swap_v2_contract), data, gas_limit) + .sign_and_send_transaction(U256::from(0), Action::Call(taker_swap_v2_contract), data, gas_limit) .compat() .await?; Ok(approve_tx) @@ -306,7 +306,7 @@ impl EthCoin { let data = try_tx_s!(self.prepare_taker_refund_payment_timelock_data(args).await); self.sign_and_send_transaction( - 0.into(), + U256::from(0), Action::Call(taker_swap_v2_contract), data, U256::from(gas_limit), @@ -364,7 +364,7 @@ impl EthCoin { let data = try_tx_s!(self.prepare_taker_refund_payment_secret_data(&refund_args).await); self.sign_and_send_transaction( - 0.into(), + U256::from(0), Action::Call(taker_swap_v2_contract), data, U256::from(gas_limit), @@ -429,7 +429,7 @@ impl EthCoin { }; let spend_payment_tx = self - .sign_and_send_transaction(0.into(), Action::Call(taker_swap_v2_contract), data, gas_limit) + .sign_and_send_transaction(U256::from(0), Action::Call(taker_swap_v2_contract), data, gas_limit) .compat() .await?; Ok(spend_payment_tx) @@ -462,7 +462,7 @@ impl EthCoin { if now > wait_until { return MmError::err(WaitForTakerPaymentSpendError::Timeout { wait_until, now }); } - Timer::sleep(10.).await; + Timer::sleep(1.).await; } } diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 50b8a354b7..04c3341e5a 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -2046,7 +2046,7 @@ fn send_approve_and_spend_erc20() { #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { - thread::sleep(Duration::from_secs(60)); + thread::sleep(Duration::from_secs(70)); let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); From bce175238601e72192a548ad593f45bb6c8da536 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 14 Aug 2024 17:22:35 +0700 Subject: [PATCH 198/233] review: update wrapper docs --- mm2src/coins/eth.rs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 895c926004..b45651c7b5 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7074,13 +7074,12 @@ impl Eip1559Ops for EthCoin { #[async_trait] impl TakerCoinSwapOpsV2 for EthCoin { - /// Calls `"ethTakerPayment"` or `"erc20TakerPayment"` swap contract methods. - /// Returns taker sent payment transaction. + /// Wrapper for [EthCoin::send_taker_funding_impl] async fn send_taker_funding(&self, args: SendTakerFundingArgs<'_>) -> Result { self.send_taker_funding_impl(args).await } - /// Validates taker payment transaction. + /// Wrapper for [EthCoin::validate_taker_funding_impl] async fn validate_taker_funding(&self, args: ValidateTakerFundingArgs<'_, Self>) -> ValidateSwapV2TxResult { self.validate_taker_funding_impl(args).await } @@ -7099,8 +7098,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { self.refund_taker_funding_secret_impl(args).await } - /// Checks that taker payment state is `TakerApproved`. - /// Accepts taker approve payment transaction and returns it if the state is correct. + /// Wrapper for [EthCoin::search_for_taker_funding_spend_impl] async fn search_for_taker_funding_spend( &self, tx: &Self::Tx, @@ -7131,8 +7129,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { Ok(()) } - /// Taker approves payment calling `takerPaymentApprove` for EVM based chains. - /// Function accepts taker payment transaction, returns taker approve payment transaction. + /// Wrapper for [EthCoin::taker_payment_approve] async fn sign_and_send_taker_funding_spend( &self, _preimage: &TxPreimageWithSig, @@ -7171,8 +7168,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { Ok(()) } - /// Taker swap contract `spendTakerPayment` method is called for EVM based chains. - /// Returns maker spent payment transaction. + /// Wrapper for [EthCoin::sign_and_broadcast_taker_payment_spend_impl] async fn sign_and_broadcast_taker_payment_spend( &self, _preimage: &TxPreimageWithSig, @@ -7183,8 +7179,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { self.sign_and_broadcast_taker_payment_spend_impl(gen_args, secret).await } - /// Checks that taker payment state is `MakerSpent`. - /// Accepts maker spent payment transaction and returns it if payment status is correct. + /// Wrapper for [EthCoin::wait_for_taker_payment_spend_impl] async fn wait_for_taker_payment_spend( &self, taker_payment: &Self::Tx, From 2ee4ef1cb1dbf21393a43a1596dc95cc60ba3d63 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 14 Aug 2024 18:06:22 +0700 Subject: [PATCH 199/233] review: etomic_swap_id_v2 with time_lock: u64 --- mm2src/coins/eth.rs | 13 +++++++-- mm2src/coins/eth/eth_swap_v2.rs | 45 ++++++++++------------------- mm2src/coins/eth/nft_swap_v2/mod.rs | 15 ++-------- 3 files changed, 30 insertions(+), 43 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index b45651c7b5..93a32d3696 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -831,9 +831,18 @@ impl EthCoinImpl { /// The id used to differentiate payments on Etomic swap smart contract pub(crate) fn etomic_swap_id(&self, time_lock: u32, secret_hash: &[u8]) -> Vec { let timelock_bytes = time_lock.to_le_bytes(); + self.generate_etomic_swap_id(&timelock_bytes, secret_hash) + } + + /// The id used to differentiate payments on Etomic swap v2 smart contracts + pub(crate) fn etomic_swap_id_v2(&self, time_lock: u64, secret_hash: &[u8]) -> Vec { + let timelock_bytes = time_lock.to_le_bytes(); + self.generate_etomic_swap_id(&timelock_bytes, secret_hash) + } - let mut input = Vec::with_capacity(timelock_bytes.len() + secret_hash.len()); - input.extend_from_slice(&timelock_bytes); + fn generate_etomic_swap_id(&self, time_lock_bytes: &[u8], secret_hash: &[u8]) -> Vec { + let mut input = Vec::with_capacity(time_lock_bytes.len() + secret_hash.len()); + input.extend_from_slice(time_lock_bytes); input.extend_from_slice(secret_hash); sha256(&input).to_vec() } diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 3e51d0f690..da17d53b40 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -15,7 +15,6 @@ use futures::compat::Future01CompatExt; use mm2_err_handle::prelude::{MapToMmResult, MmError, MmResult}; use mm2_number::BigDecimal; use std::convert::TryInto; -use std::num::TryFromIntError; use web3::types::{Transaction as Web3Tx, TransactionId}; const ETH_TAKER_PAYMENT: &str = "ethTakerPayment"; @@ -28,8 +27,8 @@ struct TakerFundingArgs { maker_address: Address, taker_secret_hash: [u8; 32], maker_secret_hash: [u8; 32], - funding_time_lock: u32, - payment_time_lock: u32, + funding_time_lock: u64, + payment_time_lock: u64, } struct TakerRefundArgs { @@ -39,7 +38,7 @@ struct TakerRefundArgs { taker_secret: [u8; 32], taker_secret_hash: [u8; 32], maker_secret_hash: [u8; 32], - payment_time_lock: u32, + payment_time_lock: u64, token_address: Address, } @@ -64,16 +63,14 @@ impl EthCoin { )); let funding_args = { let maker_address = public_to_address(&Public::from_slice(args.maker_pub)); - let funding_time_lock: u32 = try_tx_s!(args.funding_time_lock.try_into()); - let payment_time_lock: u32 = try_tx_s!(args.payment_time_lock.try_into()); TakerFundingArgs { dex_fee, payment_amount, maker_address, taker_secret_hash: try_tx_s!(args.taker_secret_hash.try_into()), maker_secret_hash: try_tx_s!(args.maker_secret_hash.try_into()), - funding_time_lock, - payment_time_lock, + funding_time_lock: args.funding_time_lock, + payment_time_lock: args.payment_time_lock, } }; match &self.coin_type { @@ -150,15 +147,7 @@ impl EthCoin { validate_payment_args(args.taker_secret_hash, args.maker_secret_hash, &args.trading_amount) .map_err(ValidateSwapV2TxError::Internal)?; let taker_address = public_to_address(args.taker_pub); - let funding_time_lock: u32 = args - .funding_time_lock - .try_into() - .map_to_mm(|e: TryFromIntError| ValidateSwapV2TxError::Overflow(e.to_string()))?; - let payment_time_lock: u32 = args - .payment_time_lock - .try_into() - .map_to_mm(|e: TryFromIntError| ValidateSwapV2TxError::Overflow(e.to_string()))?; - let swap_id = self.etomic_swap_id(payment_time_lock, args.maker_secret_hash); + let swap_id = self.etomic_swap_id_v2(args.payment_time_lock, args.maker_secret_hash); let taker_status = self .payment_status_v2( taker_swap_v2_contract, @@ -194,8 +183,8 @@ impl EthCoin { receiver: self.my_addr().await, taker_secret_hash: args.taker_secret_hash, maker_secret_hash: args.maker_secret_hash, - funding_time_lock, - payment_time_lock, + funding_time_lock: args.funding_time_lock, + payment_time_lock: args.payment_time_lock, } }; match self.coin_type { @@ -280,7 +269,6 @@ impl EthCoin { self.decimals )); let maker_address = public_to_address(&Public::from_slice(args.maker_pub)); - let payment_time_lock: u32 = try_tx_s!(args.time_lock.try_into()); let (maker_secret_hash, taker_secret_hash) = match args.tx_type_with_secret_hash { SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash, @@ -300,7 +288,7 @@ impl EthCoin { taker_secret: [0u8; 32], taker_secret_hash: try_tx_s!(taker_secret_hash.try_into()), maker_secret_hash: try_tx_s!(maker_secret_hash.try_into()), - payment_time_lock, + payment_time_lock: args.time_lock, token_address, }; let data = try_tx_s!(self.prepare_taker_refund_payment_timelock_data(args).await); @@ -349,7 +337,6 @@ impl EthCoin { self.decimals )); let maker_address = public_to_address(args.maker_pubkey); - let payment_time_lock: u32 = try_tx_s!(args.payment_time_lock.try_into()); let refund_args = TakerRefundArgs { dex_fee, @@ -358,7 +345,7 @@ impl EthCoin { taker_secret, taker_secret_hash: [0u8; 32], maker_secret_hash, - payment_time_lock, + payment_time_lock: args.payment_time_lock, token_address, }; let data = try_tx_s!(self.prepare_taker_refund_payment_secret_data(&refund_args).await); @@ -477,7 +464,7 @@ impl EthCoin { /// uint32 paymentLockTime async fn prepare_taker_eth_funding_data(&self, args: &TakerFundingArgs) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function(ETH_TAKER_PAYMENT)?; - let id = self.etomic_swap_id(args.payment_time_lock, &args.maker_secret_hash); + let id = self.etomic_swap_id_v2(args.payment_time_lock, &args.maker_secret_hash); let data = function.encode_input(&[ Token::FixedBytes(id), Token::Uint(args.dex_fee), @@ -507,7 +494,7 @@ impl EthCoin { token_address: Address, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function(ERC20_TAKER_PAYMENT)?; - let id = self.etomic_swap_id(args.payment_time_lock, &args.maker_secret_hash); + let id = self.etomic_swap_id_v2(args.payment_time_lock, &args.maker_secret_hash); let data = function.encode_input(&[ Token::FixedBytes(id), Token::Uint(args.payment_amount), @@ -535,7 +522,7 @@ impl EthCoin { args: TakerRefundArgs, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("refundTakerPaymentTimelock")?; - let id = self.etomic_swap_id(args.payment_time_lock, &args.maker_secret_hash); + let id = self.etomic_swap_id_v2(args.payment_time_lock, &args.maker_secret_hash); let data = function.encode_input(&[ Token::FixedBytes(id), Token::Uint(args.payment_amount), @@ -562,7 +549,7 @@ impl EthCoin { args: &TakerRefundArgs, ) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function("refundTakerPaymentSecret")?; - let id = self.etomic_swap_id(args.payment_time_lock, &args.maker_secret_hash); + let id = self.etomic_swap_id_v2(args.payment_time_lock, &args.maker_secret_hash); let data = function.encode_input(&[ Token::FixedBytes(id), Token::Uint(args.payment_amount), @@ -798,8 +785,8 @@ struct TakerValidationArgs<'a> { receiver: Address, taker_secret_hash: &'a [u8], maker_secret_hash: &'a [u8], - funding_time_lock: u32, - payment_time_lock: u32, + funding_time_lock: u64, + payment_time_lock: u64, } /// Validation function for ETH taker payment data diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index 2497c3737e..5f2bfe61dc 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -6,7 +6,6 @@ use ethkey::public_to_address; use futures::compat::Future01CompatExt; use mm2_err_handle::prelude::{MapToMmResult, MmError, MmResult}; use mm2_number::BigDecimal; -use std::convert::TryInto; use web3::types::TransactionId; pub(crate) mod errors; @@ -70,11 +69,7 @@ impl EthCoin { let etomic_swap_contract = args.nft_swap_info.swap_contract_address; let token_address = args.nft_swap_info.token_address; let maker_address = public_to_address(args.maker_pub); - let time_lock_u32 = args - .time_lock - .try_into() - .map_err(ValidatePaymentError::TimelockOverflow)?; - let swap_id = self.etomic_swap_id(time_lock_u32, args.maker_secret_hash); + let swap_id = self.etomic_swap_id_v2(args.time_lock, args.maker_secret_hash); let maker_status = self .payment_status_v2( *etomic_swap_contract, @@ -294,18 +289,14 @@ impl EthCoin { fn prepare_htlc_data(&self, args: &SendNftMakerPaymentArgs<'_, Self>) -> Result, PrepareTxDataError> { let taker_address = public_to_address(args.taker_pub); - let time_lock_u32 = args - .time_lock - .try_into() - .map_err(|e| PrepareTxDataError::Internal(ERRL!("{}", e)))?; - let id = self.etomic_swap_id(time_lock_u32, args.maker_secret_hash); + let id = self.etomic_swap_id_v2(args.time_lock, args.maker_secret_hash); let encoded = ethabi::encode(&[ Token::FixedBytes(id), Token::Address(taker_address), Token::Address(*args.nft_swap_info.token_address), Token::FixedBytes(args.taker_secret_hash.to_vec()), Token::FixedBytes(args.maker_secret_hash.to_vec()), - Token::Uint(U256::from(time_lock_u32)), + Token::Uint(U256::from(args.time_lock)), ]); Ok(encoded) } From a5765b1a285849bacc686ac945b82d5398fa307f Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 15 Aug 2024 10:27:44 +0700 Subject: [PATCH 200/233] dont wait pending tx for validate_taker_funding --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 04c3341e5a..beda43695f 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1872,7 +1872,6 @@ fn send_approve_and_spend_eth() { trading_amount: trading_amount.clone(), swap_unique_data: &[], }; - wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); block_on(maker_coin.validate_taker_funding(validate)).unwrap(); let approve_args = GenTakerFundingSpendArgs { @@ -1888,7 +1887,6 @@ fn send_approve_and_spend_eth() { preimage: funding_tx.clone(), signature: taker_coin.parse_signature(&[0u8; 65]).unwrap(), }; - wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let taker_approve_tx = block_on(taker_coin.sign_and_send_taker_funding_spend(&preimage, &approve_args, &[])).unwrap(); @@ -1984,7 +1982,6 @@ fn send_approve_and_spend_erc20() { trading_amount: trading_amount.clone(), swap_unique_data: &[], }; - wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); block_on(maker_coin.validate_taker_funding(validate)).unwrap(); let approve_args = GenTakerFundingSpendArgs { @@ -2000,7 +1997,6 @@ fn send_approve_and_spend_erc20() { preimage: funding_tx.clone(), signature: taker_coin.parse_signature(&[0u8; 65]).unwrap(), }; - wait_pending_transactions(Address::from_slice(maker_address.as_bytes())); wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let taker_approve_tx = block_on(taker_coin.sign_and_send_taker_funding_spend(&preimage, &approve_args, &[])).unwrap(); @@ -2046,7 +2042,6 @@ fn send_approve_and_spend_erc20() { #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { - thread::sleep(Duration::from_secs(70)); let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); From 006963ad17f3348986593f8a1d43656a732d0462 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 15 Aug 2024 10:44:45 +0700 Subject: [PATCH 201/233] move send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20 at the end --- .../tests/docker_tests/eth_docker_tests.rs | 118 +++++++++--------- 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index beda43695f..b887079433 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1639,7 +1639,7 @@ fn eth_coin_v2_activation_with_random_privkey( #[test] fn send_and_refund_taker_funding_by_secret_eth() { // sepolia test - thread::sleep(Duration::from_secs(6)); + thread::sleep(Duration::from_secs(5)); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); @@ -2041,22 +2041,21 @@ fn send_approve_and_spend_erc20() { } #[test] -fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { - let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); - let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); - let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); +fn send_and_refund_taker_funding_exceed_payment_timelock_eth() { + // sepolia test + thread::sleep(Duration::from_secs(25)); + let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); + let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); let taker_secret = vec![0; 32]; let taker_secret_hash = sha256(&taker_secret).to_vec(); let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); + let funding_time_lock = now_sec() + 3000; + let payment_time_lock = now_sec() - 1000; let taker_address = block_on(taker_coin.my_addr()); - // if TakerPaymentState is `PaymentSent` then timestamp should exceed payment pre-approve lock time (funding_time_lock) - let funding_time_lock = now_sec() + 29; - let payment_time_lock = now_sec() + 1000; - let dex_fee = &DexFee::Standard("0.00001".into()); let trading_amount = BigDecimal::from_str("0.0001").unwrap(); @@ -2074,15 +2073,36 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { }; wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); - log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 150); - thread::sleep(Duration::from_secs(29)); + log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); + wait_for_confirmations(&taker_coin, &funding_tx, 100); + + let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); + let approve_args = GenTakerFundingSpendArgs { + funding_tx: &funding_tx, + maker_pub, + taker_pub, + funding_time_lock, + taker_secret_hash: &taker_secret_hash, + taker_payment_time_lock: funding_time_lock, + maker_secret_hash: &maker_secret_hash, + }; + let preimage = TxPreimageWithSig { + preimage: funding_tx.clone(), + signature: taker_coin.parse_signature(&[0u8; 65]).unwrap(), + }; + wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + let taker_approve_tx = + block_on(taker_coin.sign_and_send_taker_funding_spend(&preimage, &approve_args, &[])).unwrap(); + log!( + "Taker approved ETH payment, tx hash: {:02x}", + taker_approve_tx.tx_hash() + ); + wait_for_confirmations(&taker_coin, &taker_approve_tx, 100); let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash: &maker_secret_hash, taker_secret_hash: &taker_secret_hash, }; - let refund_args = RefundTakerPaymentArgs { payment_tx: &funding_tx.to_bytes(), time_lock: payment_time_lock, @@ -2095,28 +2115,28 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { trading_amount, }; wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); - thread::sleep(Duration::from_secs(3)); let funding_tx_refund = block_on(taker_coin.refund_taker_funding_timelock(refund_args)).unwrap(); log!( - "Taker refunded ERC20 funding after pre-approval lock time was exceeded, tx hash: {:02x}", + "Taker refunded ETH funding after payment lock time was exceeded, tx hash: {:02x}", funding_tx_refund.tx_hash() ); - wait_for_confirmations(&taker_coin, &funding_tx_refund, 150); + wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } #[test] -fn send_and_refund_taker_funding_exceed_payment_timelock_eth() { +fn send_and_refund_taker_funding_exceed_payment_timelock_erc20() { // sepolia test - thread::sleep(Duration::from_secs(25)); - let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); - let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); + thread::sleep(Duration::from_secs(28)); + let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); + let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, erc20_conf, true); + let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, erc20_conf, true); let taker_secret = vec![0; 32]; let taker_secret_hash = sha256(&taker_secret).to_vec(); let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); - let funding_time_lock = now_sec() + 3000; - let payment_time_lock = now_sec() - 1000; + let funding_time_lock = now_sec() + 29; + let payment_time_lock = now_sec() + 15; let taker_address = block_on(taker_coin.my_addr()); @@ -2137,8 +2157,9 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_eth() { }; wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); - log!("Taker sent ETH funding, tx hash: {:02x}", funding_tx.tx_hash()); + log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); wait_for_confirmations(&taker_coin, &funding_tx, 100); + thread::sleep(Duration::from_secs(16)); let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); let approve_args = GenTakerFundingSpendArgs { @@ -2158,7 +2179,7 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_eth() { let taker_approve_tx = block_on(taker_coin.sign_and_send_taker_funding_spend(&preimage, &approve_args, &[])).unwrap(); log!( - "Taker approved ETH payment, tx hash: {:02x}", + "Taker approved ERC20 payment, tx hash: {:02x}", taker_approve_tx.tx_hash() ); wait_for_confirmations(&taker_coin, &taker_approve_tx, 100); @@ -2181,29 +2202,31 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_eth() { wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx_refund = block_on(taker_coin.refund_taker_funding_timelock(refund_args)).unwrap(); log!( - "Taker refunded ETH funding after payment lock time was exceeded, tx hash: {:02x}", + "Taker refunded ERC20 funding after payment lock time was exceeded, tx hash: {:02x}", funding_tx_refund.tx_hash() ); wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } #[test] -fn send_and_refund_taker_funding_exceed_payment_timelock_erc20() { +fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { // sepolia test - thread::sleep(Duration::from_secs(28)); + thread::sleep(Duration::from_secs(70)); let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); - let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, erc20_conf, true); - let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, erc20_conf, true); + let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); + let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); let taker_secret = vec![0; 32]; let taker_secret_hash = sha256(&taker_secret).to_vec(); let maker_secret = vec![1; 32]; let maker_secret_hash = sha256(&maker_secret).to_vec(); - let funding_time_lock = now_sec() + 29; - let payment_time_lock = now_sec() + 15; let taker_address = block_on(taker_coin.my_addr()); + // if TakerPaymentState is `PaymentSent` then timestamp should exceed payment pre-approve lock time (funding_time_lock) + let funding_time_lock = now_sec() + 29; + let payment_time_lock = now_sec() + 1000; + let dex_fee = &DexFee::Standard("0.00001".into()); let trading_amount = BigDecimal::from_str("0.0001").unwrap(); @@ -2222,36 +2245,14 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_erc20() { wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 100); - thread::sleep(Duration::from_secs(16)); - - let taker_pub = &taker_coin.derive_htlc_pubkey_v2(&[]); - let approve_args = GenTakerFundingSpendArgs { - funding_tx: &funding_tx, - maker_pub, - taker_pub, - funding_time_lock, - taker_secret_hash: &taker_secret_hash, - taker_payment_time_lock: funding_time_lock, - maker_secret_hash: &maker_secret_hash, - }; - let preimage = TxPreimageWithSig { - preimage: funding_tx.clone(), - signature: taker_coin.parse_signature(&[0u8; 65]).unwrap(), - }; - wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); - let taker_approve_tx = - block_on(taker_coin.sign_and_send_taker_funding_spend(&preimage, &approve_args, &[])).unwrap(); - log!( - "Taker approved ERC20 payment, tx hash: {:02x}", - taker_approve_tx.tx_hash() - ); - wait_for_confirmations(&taker_coin, &taker_approve_tx, 100); + wait_for_confirmations(&taker_coin, &funding_tx, 150); + thread::sleep(Duration::from_secs(29)); let tx_type_with_secret_hash = SwapTxTypeWithSecretHash::TakerPaymentV2 { maker_secret_hash: &maker_secret_hash, taker_secret_hash: &taker_secret_hash, }; + let refund_args = RefundTakerPaymentArgs { payment_tx: &funding_tx.to_bytes(), time_lock: payment_time_lock, @@ -2264,10 +2265,11 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_erc20() { trading_amount, }; wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); + thread::sleep(Duration::from_secs(3)); let funding_tx_refund = block_on(taker_coin.refund_taker_funding_timelock(refund_args)).unwrap(); log!( - "Taker refunded ERC20 funding after payment lock time was exceeded, tx hash: {:02x}", + "Taker refunded ERC20 funding after pre-approval lock time was exceeded, tx hash: {:02x}", funding_tx_refund.tx_hash() ); - wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); + wait_for_confirmations(&taker_coin, &funding_tx_refund, 150); } From a8594144ba0348665f327144db9d295e92eb7f9a Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 15 Aug 2024 11:28:55 +0700 Subject: [PATCH 202/233] re-check payment state in fncs `taker_payment_approve` and `sign_and_broadcast_taker_payment_spend_impl` --- mm2src/coins/eth/eth_swap_v2.rs | 61 ++++++++++++------- .../tests/docker_tests/eth_docker_tests.rs | 6 +- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index da17d53b40..8e62cef276 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -222,14 +222,23 @@ impl EthCoin { let (taker_swap_v2_contract, send_func, token_address) = self .taker_swap_v2_details(ETH_TAKER_PAYMENT, ERC20_TAKER_PAYMENT) .await?; - // Note: `PaymentSent` state was checked in `validate_taker_funding`. So we don't have to validate it in prepare function - let data = { - let decoded = try_tx_s!(decode_contract_call(send_func, args.funding_tx.unsigned().data())); - try_tx_s!( - self.prepare_taker_payment_approve_data(args, decoded, token_address) - .await + let decoded = try_tx_s!(decode_contract_call(send_func, args.funding_tx.unsigned().data())); + let taker_status = try_tx_s!( + self.payment_status_v2( + taker_swap_v2_contract, + decoded[0].clone(), + &TAKER_SWAP_V2, + EthPaymentType::TakerPayments, + 3, ) - }; + .await + ); + validate_payment_state(args.funding_tx, taker_status, TakerPaymentStateV2::PaymentSent as u8) + .map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?; + let data = try_tx_s!( + self.prepare_taker_payment_approve_data(args, decoded, token_address) + .await + ); let approve_tx = self .sign_and_send_transaction(U256::from(0), Action::Call(taker_swap_v2_contract), data, gas_limit) .compat() @@ -406,15 +415,27 @@ impl EthCoin { let (taker_swap_v2_contract, approve_func, token_address) = self .taker_swap_v2_details(TAKER_PAYMENT_APPROVE, TAKER_PAYMENT_APPROVE) .await?; - // Note: `TakerApproved` status was checked in `search_for_taker_funding_spend` function - let data = { - let decoded = try_tx_s!(decode_contract_call(approve_func, gen_args.taker_tx.unsigned().data())); - try_tx_s!( - self.prepare_spend_taker_payment_data(gen_args, secret, decoded, token_address) - .await + let decoded = try_tx_s!(decode_contract_call(approve_func, gen_args.taker_tx.unsigned().data())); + let taker_status = try_tx_s!( + self.payment_status_v2( + taker_swap_v2_contract, + decoded[0].clone(), + &TAKER_SWAP_V2, + EthPaymentType::TakerPayments, + 3, ) - }; - + .await + ); + validate_payment_state( + gen_args.taker_tx, + taker_status, + TakerPaymentStateV2::TakerApproved as u8, + ) + .map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?; + let data = try_tx_s!( + self.prepare_spend_taker_payment_data(gen_args, secret, decoded, token_address) + .await + ); let spend_payment_tx = self .sign_and_send_transaction(U256::from(0), Action::Call(taker_swap_v2_contract), data, gas_limit) .compat() @@ -758,7 +779,7 @@ pub(crate) fn validate_from_to_and_status( ) -> Result<(), MmError> { if status != U256::from(expected_status) { return MmError::err(ValidatePaymentV2Err::UnexpectedPaymentState(format!( - "Payment state is not PaymentSent, got {}", + "Payment state is not `PaymentSent`, got {}", status ))); } @@ -868,11 +889,9 @@ pub(crate) fn validate_payment_state( expected_state: u8, ) -> Result<(), PrepareTxDataError> { if state != U256::from(expected_state) { - return Err(PrepareTxDataError::Internal(ERRL!( - "Payment {:?} state is not {}, got {}", - tx, - expected_state, - state + return Err(PrepareTxDataError::Internal(format!( + "Payment {:?} state is not `{}`, got `{}`", + tx, expected_state, state ))); } Ok(()) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index b887079433..cc1c217673 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1733,7 +1733,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); - wait_for_confirmations(&taker_coin, &funding_tx, 150); + wait_for_confirmations(&taker_coin, &funding_tx, 200); let refund_args = RefundFundingSecretArgs { funding_tx: &funding_tx, @@ -1755,7 +1755,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { "Taker refunded ERC20 funding by secret, tx hash: {:02x}", funding_tx_refund.tx_hash() ); - wait_for_confirmations(&taker_coin, &funding_tx_refund, 150); + wait_for_confirmations(&taker_coin, &funding_tx_refund, 200); } #[test] @@ -2211,7 +2211,7 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_erc20() { #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { // sepolia test - thread::sleep(Duration::from_secs(70)); + thread::sleep(Duration::from_secs(200)); let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); From 738731c47d028d5e3b44e4b90b89783cdc95e483 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 15 Aug 2024 12:22:34 +0700 Subject: [PATCH 203/233] change sleep duration for send_and_refund_taker_funding_by_secret_erc20 --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index cc1c217673..d07d63535a 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1699,6 +1699,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { #[test] fn send_and_refund_taker_funding_by_secret_erc20() { + thread::sleep(Duration::from_secs(90)); let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); @@ -1729,7 +1730,6 @@ fn send_and_refund_taker_funding_by_secret_erc20() { swap_unique_data: &[], }; - thread::sleep(Duration::from_secs(4)); wait_pending_transactions(Address::from_slice(taker_address.as_bytes())); let funding_tx = block_on(taker_coin.send_taker_funding(payment_args)).unwrap(); log!("Taker sent ERC20 funding, tx hash: {:02x}", funding_tx.tx_hash()); From d9e3c4ead8a166e571c28303f2d2d238f68b846f Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 15 Aug 2024 15:18:41 +0700 Subject: [PATCH 204/233] review: provide const ZERO_VALUE --- mm2src/coins/eth/eth_swap_v2.rs | 25 ++++++++++++++++++++----- mm2src/coins/eth/nft_swap_v2/mod.rs | 11 ++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 8e62cef276..4143359284 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -17,6 +17,11 @@ use mm2_number::BigDecimal; use std::convert::TryInto; use web3::types::{Transaction as Web3Tx, TransactionId}; +/// ZERO_VALUE is used to represent a 0 amount in transactions where the value is encoded in the transaction input data. +/// This is typically used in function calls where the value is not directly transferred with the transaction, such as in +/// `spendTakerPayment` where the [amount](https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapTakerV2.sol#L166) +/// is provided as part of the input data rather than as an Ether value +pub(crate) const ZERO_VALUE: u32 = 0; const ETH_TAKER_PAYMENT: &str = "ethTakerPayment"; const ERC20_TAKER_PAYMENT: &str = "erc20TakerPayment"; const TAKER_PAYMENT_APPROVE: &str = "takerPaymentApprove"; @@ -113,7 +118,7 @@ impl EthCoin { })?; } self.sign_and_send_transaction( - U256::from(0), + U256::from(ZERO_VALUE), Action::Call(taker_swap_v2_contract), data, // TODO need new consts and params for v2 calls. now it uses v1 @@ -240,7 +245,12 @@ impl EthCoin { .await ); let approve_tx = self - .sign_and_send_transaction(U256::from(0), Action::Call(taker_swap_v2_contract), data, gas_limit) + .sign_and_send_transaction( + U256::from(ZERO_VALUE), + Action::Call(taker_swap_v2_contract), + data, + gas_limit, + ) .compat() .await?; Ok(approve_tx) @@ -303,7 +313,7 @@ impl EthCoin { let data = try_tx_s!(self.prepare_taker_refund_payment_timelock_data(args).await); self.sign_and_send_transaction( - U256::from(0), + U256::from(ZERO_VALUE), Action::Call(taker_swap_v2_contract), data, U256::from(gas_limit), @@ -360,7 +370,7 @@ impl EthCoin { let data = try_tx_s!(self.prepare_taker_refund_payment_secret_data(&refund_args).await); self.sign_and_send_transaction( - U256::from(0), + U256::from(ZERO_VALUE), Action::Call(taker_swap_v2_contract), data, U256::from(gas_limit), @@ -437,7 +447,12 @@ impl EthCoin { .await ); let spend_payment_tx = self - .sign_and_send_transaction(U256::from(0), Action::Call(taker_swap_v2_contract), data, gas_limit) + .sign_and_send_transaction( + U256::from(ZERO_VALUE), + Action::Call(taker_swap_v2_contract), + data, + gas_limit, + ) .compat() .await?; Ok(spend_payment_tx) diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index 5f2bfe61dc..77eaf84be0 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -14,7 +14,8 @@ mod structs; use structs::{ExpectedHtlcParams, ValidationParams}; use super::ContractType; -use crate::eth::eth_swap_v2::{validate_from_to_and_status, validate_payment_state, EthPaymentType, PaymentStatusErr}; +use crate::eth::eth_swap_v2::{validate_from_to_and_status, validate_payment_state, EthPaymentType, PaymentStatusErr, + ZERO_VALUE}; use crate::eth::{decode_contract_call, EthCoin, EthCoinType, MakerPaymentStateV2, SignedEthTx, ERC1155_CONTRACT, ERC721_CONTRACT, NFT_MAKER_SWAP_V2}; use crate::{ParseCoinAssocTypes, RefundNftMakerPaymentArgs, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, @@ -37,7 +38,7 @@ impl EthCoin { let data = try_tx_s!(self.prepare_nft_maker_payment_v2_data(&args, htlc_data).await); self.sign_and_send_transaction( - 0.into(), + ZERO_VALUE.into(), Action::Call(*args.nft_swap_info.token_address), data, U256::from(self.gas_limit.eth_max_trade_gas), // TODO: fix to a more accurate const or estimated value @@ -160,7 +161,7 @@ impl EthCoin { ); let data = try_tx_s!(self.prepare_spend_nft_maker_v2_data(&args, decoded, htlc_params, state)); self.sign_and_send_transaction( - 0.into(), + ZERO_VALUE.into(), Action::Call(*etomic_swap_contract), data, U256::from(self.gas_limit.eth_max_trade_gas), // TODO: fix to a more accurate const or estimated value @@ -200,7 +201,7 @@ impl EthCoin { let data = try_tx_s!(self.prepare_refund_nft_maker_payment_v2_timelock(&args, decoded, htlc_params, state)); self.sign_and_send_transaction( - 0.into(), + ZERO_VALUE.into(), Action::Call(*etomic_swap_contract), data, U256::from(self.gas_limit.eth_max_trade_gas), // TODO: fix to a more accurate const or estimated value @@ -241,7 +242,7 @@ impl EthCoin { let data = try_tx_s!(self.prepare_refund_nft_maker_payment_v2_secret(&args, decoded, htlc_params, state)); self.sign_and_send_transaction( - 0.into(), + ZERO_VALUE.into(), Action::Call(*etomic_swap_contract), data, U256::from(self.gas_limit.eth_max_trade_gas), // TODO: fix to a more accurate const or estimated value From e1144d1aa2c04ae520eb1abfe0f8f62707b2a4e3 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 18 Aug 2024 22:13:41 +0700 Subject: [PATCH 205/233] review: fix missed maker_secret_hash, unify EthCoinType match arms --- mm2src/coins/eth/eth_swap_v2.rs | 3 +-- mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 4143359284..2c71570af2 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -216,8 +216,7 @@ impl EthCoin { ) -> Result { // TODO need new consts and params for v2 calls, here should be common `gas_limit.taker_approve` param for Eth and Erc20 let gas_limit = match self.coin_type { - EthCoinType::Eth => U256::from(self.gas_limit.eth_payment), - EthCoinType::Erc20 { .. } => U256::from(self.gas_limit.eth_payment), + EthCoinType::Eth | EthCoinType::Erc20 { .. } => U256::from(self.gas_limit.eth_payment), EthCoinType::Nft { .. } => { return Err(TransactionErr::ProtocolNotSupported(ERRL!( "NFT protocol is not supported for ETH and ERC20 Swaps" diff --git a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs index f1fa160cb4..fb419b1981 100644 --- a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs @@ -1162,7 +1162,7 @@ impl Date: Sun, 18 Aug 2024 22:20:12 +0700 Subject: [PATCH 206/233] review: fix timelocks doc comms, make them clearer. --- mm2src/coins/lp_coins.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index aabd8cfca3..ced6a3c8d9 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1375,10 +1375,11 @@ pub struct GenTakerFundingSpendArgs<'a, Coin: ParseCoinAssocTypes + ?Sized> { pub struct ValidateTakerFundingArgs<'a, Coin: ParseCoinAssocTypes + ?Sized> { /// Taker funding transaction pub funding_tx: &'a Coin::Tx, - /// The timestamp after which the taker can refund the funding transaction if the maker hasn't pre-approved the transaction + /// In EVM case: The timestamp after which the taker can refund the funding transaction if the taker hasn't pre-approved the transaction /// In UTXO case: Taker will be able to refund the payment after this timestamp pub funding_time_lock: u64, - /// The timestamp after which the taker can refund the payment transaction if the maker hasn't claimed it by revealing their secret + /// In EVM case: The timestamp after which the taker can refund the payment transaction if the maker hasn't claimed it by revealing their secret. + /// UTXO doesn't use it pub payment_time_lock: u64, /// The hash of the secret generated by taker pub taker_secret_hash: &'a [u8], From adb69d59ff56a7e8205b21edd1e8305ae6434bfb Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 19 Aug 2024 17:24:46 +0700 Subject: [PATCH 207/233] review: provide RefundMakerPaymentTimelockArgs, RefundMakerPaymentSecretArgs in maker opsv2 --- mm2src/coins/lp_coins.rs | 34 +++++------ mm2src/coins/utxo/utxo_common.rs | 4 +- mm2src/coins/utxo/utxo_standard.rs | 61 ++++++++++++++----- mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs | 12 ++-- .../tests/docker_tests/swap_proto_v2_tests.rs | 14 ++--- 5 files changed, 78 insertions(+), 47 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index ced6a3c8d9..1d22edb526 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -990,6 +990,17 @@ pub struct RefundPaymentArgs<'a> { pub watcher_reward: bool, } +#[derive(Debug)] +pub struct RefundMakerPaymentTimelockArgs<'a> { + pub payment_tx: &'a [u8], + pub time_lock: u64, + pub taker_pub: &'a [u8], + pub tx_type_with_secret_hash: SwapTxTypeWithSecretHash<'a>, + pub swap_contract_address: &'a Option, + pub swap_unique_data: &'a [u8], + pub watcher_reward: bool, +} + #[derive(Debug)] pub struct RefundTakerPaymentArgs<'a> { pub payment_tx: &'a [u8], @@ -1005,20 +1016,6 @@ pub struct RefundTakerPaymentArgs<'a> { pub trading_amount: BigDecimal, } -impl<'a> From> for RefundPaymentArgs<'a> { - fn from(args: RefundTakerPaymentArgs<'a>) -> RefundPaymentArgs<'a> { - RefundPaymentArgs { - payment_tx: args.payment_tx, - time_lock: args.time_lock, - other_pubkey: args.maker_pub, - tx_type_with_secret_hash: args.tx_type_with_secret_hash, - swap_contract_address: &None, - swap_unique_data: args.swap_unique_data, - watcher_reward: args.watcher_reward, - } - } -} - /// Helper struct wrapping arguments for [SwapOps::check_if_my_payment_sent]. #[derive(Clone, Debug)] pub struct CheckIfMyPaymentSentArgs<'a> { @@ -1714,7 +1711,7 @@ pub struct ValidateNftMakerPaymentArgs<'a, Coin: ParseCoinAssocTypes + ParseNftA pub nft_swap_info: &'a NftSwapInfo<'a, Coin>, } -pub struct RefundMakerPaymentArgs<'a, Coin: ParseCoinAssocTypes + ?Sized> { +pub struct RefundMakerPaymentSecretArgs<'a, Coin: ParseCoinAssocTypes + ?Sized> { /// Maker payment tx pub maker_payment_tx: &'a Coin::Tx, /// Maker will be able to refund the payment after this timestamp @@ -1796,12 +1793,15 @@ pub trait MakerCoinSwapOpsV2: ParseCoinAssocTypes + CommonSwapOpsV2 + Send + Syn async fn validate_maker_payment_v2(&self, args: ValidateMakerPaymentArgs<'_, Self>) -> ValidatePaymentResult<()>; /// Refund maker payment transaction using timelock path - async fn refund_maker_payment_v2_timelock(&self, args: RefundPaymentArgs<'_>) -> Result; + async fn refund_maker_payment_v2_timelock( + &self, + args: RefundMakerPaymentTimelockArgs<'_>, + ) -> Result; /// Refund maker payment transaction using immediate refund path async fn refund_maker_payment_v2_secret( &self, - args: RefundMakerPaymentArgs<'_, Self>, + args: RefundMakerPaymentSecretArgs<'_, Self>, ) -> Result; /// Spend maker payment transaction diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index d090522e41..175454e1da 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -15,7 +15,7 @@ use crate::watcher_common::validate_watcher_reward; use crate::{scan_for_new_addresses_impl, CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, ConfirmPaymentInput, DexFee, GenPreimageResult, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, GetWithdrawSenderAddress, RawTransactionError, RawTransactionRequest, RawTransactionRes, RawTransactionResult, - RefundFundingSecretArgs, RefundMakerPaymentArgs, RefundPaymentArgs, RewardTarget, + RefundFundingSecretArgs, RefundMakerPaymentSecretArgs, RefundPaymentArgs, RewardTarget, SearchForSwapTxSpendInput, SendMakerPaymentArgs, SendMakerPaymentSpendPreimageInput, SendPaymentArgs, SendTakerFundingArgs, SignRawTransactionEnum, SignRawTransactionRequest, SignUtxoTransactionParams, SignatureError, SignatureResult, SpendMakerPaymentArgs, SpendPaymentArgs, SwapOps, @@ -5068,7 +5068,7 @@ pub async fn spend_maker_payment_v2( /// Common implementation of maker payment v2 reclaim for UTXO coins using immediate refund path with secret reveal. pub async fn refund_maker_payment_v2_secret( coin: T, - args: RefundMakerPaymentArgs<'_, T>, + args: RefundMakerPaymentSecretArgs<'_, T>, ) -> Result where T: UtxoCommonOps + SwapOps, diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index 2753b7b1b4..2a09fe6f23 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -27,18 +27,18 @@ use crate::{CanRefundHtlc, CheckIfMyPaymentSentArgs, CoinBalance, CoinWithDeriva GenTakerPaymentSpendArgs, GetWithdrawSenderAddress, IguanaBalanceOps, IguanaPrivKey, MakerCoinSwapOpsV2, MakerSwapTakerCoin, MmCoinEnum, NegotiateSwapContractAddrErr, PaymentInstructionArgs, PaymentInstructions, PaymentInstructionsErr, PrivKeyBuildPolicy, RawTransactionRequest, RawTransactionResult, RefundError, - RefundFundingSecretArgs, RefundMakerPaymentArgs, RefundPaymentArgs, RefundResult, RefundTakerPaymentArgs, - SearchForFundingSpendErr, SearchForSwapTxSpendInput, SendMakerPaymentArgs, - SendMakerPaymentSpendPreimageInput, SendPaymentArgs, SendTakerFundingArgs, SignRawTransactionRequest, - SignatureResult, SpendMakerPaymentArgs, SpendPaymentArgs, SwapOps, SwapTxTypeWithSecretHash, - TakerCoinSwapOpsV2, TakerSwapMakerCoin, ToBytes, TradePreimageValue, TransactionFut, TransactionResult, - TxMarshalingErr, TxPreimageWithSig, ValidateAddressResult, ValidateFeeArgs, ValidateInstructionsErr, - ValidateMakerPaymentArgs, ValidateOtherPubKeyErr, ValidatePaymentError, ValidatePaymentFut, - ValidatePaymentInput, ValidateSwapV2TxResult, ValidateTakerFundingArgs, - ValidateTakerFundingSpendPreimageResult, ValidateTakerPaymentSpendPreimageResult, - ValidateWatcherSpendInput, VerificationResult, WaitForHTLCTxSpendArgs, WaitForTakerPaymentSpendError, - WatcherOps, WatcherReward, WatcherRewardError, WatcherSearchForSwapTxSpendInput, - WatcherValidatePaymentInput, WatcherValidateTakerFeeInput, WithdrawFut}; + RefundFundingSecretArgs, RefundMakerPaymentSecretArgs, RefundMakerPaymentTimelockArgs, RefundPaymentArgs, + RefundResult, RefundTakerPaymentArgs, SearchForFundingSpendErr, SearchForSwapTxSpendInput, + SendMakerPaymentArgs, SendMakerPaymentSpendPreimageInput, SendPaymentArgs, SendTakerFundingArgs, + SignRawTransactionRequest, SignatureResult, SpendMakerPaymentArgs, SpendPaymentArgs, SwapOps, + SwapTxTypeWithSecretHash, TakerCoinSwapOpsV2, TakerSwapMakerCoin, ToBytes, TradePreimageValue, + TransactionFut, TransactionResult, TxMarshalingErr, TxPreimageWithSig, ValidateAddressResult, + ValidateFeeArgs, ValidateInstructionsErr, ValidateMakerPaymentArgs, ValidateOtherPubKeyErr, + ValidatePaymentError, ValidatePaymentFut, ValidatePaymentInput, ValidateSwapV2TxResult, + ValidateTakerFundingArgs, ValidateTakerFundingSpendPreimageResult, + ValidateTakerPaymentSpendPreimageResult, ValidateWatcherSpendInput, VerificationResult, + WaitForHTLCTxSpendArgs, WaitForTakerPaymentSpendError, WatcherOps, WatcherReward, WatcherRewardError, + WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput, WatcherValidateTakerFeeInput, WithdrawFut}; use common::executor::{AbortableSystem, AbortedError}; use futures::{FutureExt, TryFutureExt}; use mm2_metrics::MetricsArc; @@ -637,13 +637,16 @@ impl MakerCoinSwapOpsV2 for UtxoStandardCoin { .await } - async fn refund_maker_payment_v2_timelock(&self, args: RefundPaymentArgs<'_>) -> Result { - utxo_common::refund_htlc_payment(self.clone(), args).await + async fn refund_maker_payment_v2_timelock( + &self, + args: RefundMakerPaymentTimelockArgs<'_>, + ) -> Result { + utxo_common::refund_htlc_payment(self.clone(), args.into()).await } async fn refund_maker_payment_v2_secret( &self, - args: RefundMakerPaymentArgs<'_, Self>, + args: RefundMakerPaymentSecretArgs<'_, Self>, ) -> Result { utxo_common::refund_maker_payment_v2_secret(self.clone(), args).await } @@ -1318,3 +1321,31 @@ impl UtxoTxHistoryOps for UtxoStandardCoin { *self.as_ref().history_sync_state.lock().unwrap() = new_state; } } + +impl<'a> From> for RefundPaymentArgs<'a> { + fn from(args: RefundTakerPaymentArgs<'a>) -> RefundPaymentArgs<'a> { + RefundPaymentArgs { + payment_tx: args.payment_tx, + time_lock: args.time_lock, + other_pubkey: args.maker_pub, + tx_type_with_secret_hash: args.tx_type_with_secret_hash, + swap_contract_address: &None, + swap_unique_data: args.swap_unique_data, + watcher_reward: args.watcher_reward, + } + } +} + +impl<'a> From> for RefundPaymentArgs<'a> { + fn from(args: RefundMakerPaymentTimelockArgs<'a>) -> RefundPaymentArgs<'a> { + RefundPaymentArgs { + payment_tx: args.payment_tx, + time_lock: args.time_lock, + other_pubkey: args.taker_pub, + tx_type_with_secret_hash: args.tx_type_with_secret_hash, + swap_contract_address: &None, + swap_unique_data: args.swap_unique_data, + watcher_reward: args.watcher_reward, + } + } +} diff --git a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs index fb419b1981..6029bd61b2 100644 --- a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs @@ -9,8 +9,8 @@ use crate::lp_swap::{swap_v2_pb::*, NO_REFUND_FEE}; use async_trait::async_trait; use bitcrypto::{dhash160, sha256}; use coins::{CanRefundHtlc, ConfirmPaymentInput, DexFee, FeeApproxStage, FundingTxSpend, GenTakerFundingSpendArgs, - GenTakerPaymentSpendArgs, MakerCoinSwapOpsV2, MmCoin, ParseCoinAssocTypes, RefundMakerPaymentArgs, - RefundPaymentArgs, SearchForFundingSpendErr, SendMakerPaymentArgs, SwapTxTypeWithSecretHash, + GenTakerPaymentSpendArgs, MakerCoinSwapOpsV2, MmCoin, ParseCoinAssocTypes, RefundMakerPaymentSecretArgs, + RefundMakerPaymentTimelockArgs, SearchForFundingSpendErr, SendMakerPaymentArgs, SwapTxTypeWithSecretHash, TakerCoinSwapOpsV2, ToBytes, TradePreimageValue, Transaction, TxPreimageWithSig, ValidateTakerFundingArgs}; use common::executor::abortable_queue::AbortableQueue; use common::executor::{AbortableSystem, Timer}; @@ -1451,7 +1451,7 @@ impl Date: Mon, 19 Aug 2024 17:26:26 +0700 Subject: [PATCH 208/233] change sleep duration in send_and_refund_taker_funding_by_secret_erc20 --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 2 +- mm2src/mm2_main/tests/docker_tests/swap_proto_v2_tests.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index d07d63535a..7ed30f1e12 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1699,7 +1699,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { #[test] fn send_and_refund_taker_funding_by_secret_erc20() { - thread::sleep(Duration::from_secs(90)); + thread::sleep(Duration::from_secs(130)); let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); let maker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); diff --git a/mm2src/mm2_main/tests/docker_tests/swap_proto_v2_tests.rs b/mm2src/mm2_main/tests/docker_tests/swap_proto_v2_tests.rs index 9b8e143d67..672ef88aa5 100644 --- a/mm2src/mm2_main/tests/docker_tests/swap_proto_v2_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/swap_proto_v2_tests.rs @@ -3,7 +3,7 @@ use bitcrypto::dhash160; use coins::utxo::UtxoCommonOps; use coins::{ConfirmPaymentInput, DexFee, FundingTxSpend, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, MakerCoinSwapOpsV2, MarketCoinOps, ParseCoinAssocTypes, RefundFundingSecretArgs, - RefundMakerPaymentSecretArgs, RefundMakerPaymentTimelockArgs, RefundPaymentArgs, RefundTakerPaymentArgs, + RefundMakerPaymentSecretArgs, RefundMakerPaymentTimelockArgs, RefundTakerPaymentArgs, SendMakerPaymentArgs, SendTakerFundingArgs, SwapTxTypeWithSecretHash, TakerCoinSwapOpsV2, Transaction, ValidateMakerPaymentArgs, ValidateTakerFundingArgs}; use common::{block_on, now_sec, DEX_FEE_ADDR_RAW_PUBKEY}; From a933c74c3d8ba7bf1595fdcdeaed372da663ad71 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 19 Aug 2024 20:43:30 +0700 Subject: [PATCH 209/233] review: return 10 sec sleep in wait_for_taker_payment_spend_impl --- mm2src/coins/eth/eth_swap_v2.rs | 2 +- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 2c71570af2..2bd5ad52b2 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -484,7 +484,7 @@ impl EthCoin { if now > wait_until { return MmError::err(WaitForTakerPaymentSpendError::Timeout { wait_until, now }); } - Timer::sleep(1.).await; + Timer::sleep(10.).await; } } diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 7ed30f1e12..3f3b8ee8be 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1825,7 +1825,6 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { #[test] fn send_approve_and_spend_eth() { // sepolia test - thread::sleep(Duration::from_secs(2)); let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); From e5bde47991038806c7a21622b43f47a513306b44 Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 19 Aug 2024 21:24:30 +0700 Subject: [PATCH 210/233] review: fix ABIError match and use InvalidData --- mm2src/coins/coin_errors.rs | 6 ++---- mm2src/coins/eth/eth_swap_v2.rs | 2 -- mm2src/coins/eth/nft_swap_v2/errors.rs | 8 ++++++-- mm2src/coins/eth/nft_swap_v2/mod.rs | 23 +++++------------------ mm2src/coins/lp_coins.rs | 8 +++----- 5 files changed, 16 insertions(+), 31 deletions(-) diff --git a/mm2src/coins/coin_errors.rs b/mm2src/coins/coin_errors.rs index 72d66ec2bd..aead751eb0 100644 --- a/mm2src/coins/coin_errors.rs +++ b/mm2src/coins/coin_errors.rs @@ -86,9 +86,7 @@ impl From for ValidatePaymentError { fn from(err: PaymentStatusErr) -> Self { match err { PaymentStatusErr::Transport(e) => Self::Transport(e), - PaymentStatusErr::ABIError(e) - | PaymentStatusErr::Internal(e) - | PaymentStatusErr::TxDeserializationError(e) => Self::InternalError(e), + PaymentStatusErr::ABIError(e) | PaymentStatusErr::Internal(e) => Self::InternalError(e), PaymentStatusErr::InvalidData(e) => Self::InvalidData(e), } } @@ -98,7 +96,7 @@ impl From for ValidatePaymentError { fn from(err: HtlcParamsError) -> Self { match err { HtlcParamsError::WrongPaymentTx(e) => ValidatePaymentError::WrongPaymentTx(e), - HtlcParamsError::TxDeserializationError(e) => ValidatePaymentError::TxDeserializationError(e), + HtlcParamsError::ABIError(e) | HtlcParamsError::InvalidData(e) => ValidatePaymentError::InvalidData(e), } } } diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 2bd5ad52b2..81b0ff8737 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -941,8 +941,6 @@ pub(crate) enum PaymentStatusErr { Transport(String), #[display(fmt = "Internal error: {}", _0)] Internal(String), - #[display(fmt = "Tx deserialization error: {}", _0)] - TxDeserializationError(String), #[display(fmt = "Invalid data error: {}", _0)] InvalidData(String), } diff --git a/mm2src/coins/eth/nft_swap_v2/errors.rs b/mm2src/coins/eth/nft_swap_v2/errors.rs index 0cbc881ff3..02cb3c7626 100644 --- a/mm2src/coins/eth/nft_swap_v2/errors.rs +++ b/mm2src/coins/eth/nft_swap_v2/errors.rs @@ -1,4 +1,5 @@ pub(crate) use crate::eth::eth_swap_v2::PrepareTxDataError; +use enum_derives::EnumFromStringify; #[derive(Debug, Display)] pub(crate) enum Erc721FunctionError { @@ -7,10 +8,13 @@ pub(crate) enum Erc721FunctionError { FunctionNotFound(String), } -#[derive(Debug, Display)] +#[derive(Debug, Display, EnumFromStringify)] pub(crate) enum HtlcParamsError { WrongPaymentTx(String), - TxDeserializationError(String), + #[from_stringify("ethabi::Error")] + #[display(fmt = "ABI error: {}", _0)] + ABIError(String), + InvalidData(String), } impl From for PrepareTxDataError { diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index 77eaf84be0..d5de6dcc86 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -410,20 +410,14 @@ impl EthCoin { let data_bytes = match decoded_data.get(index) { Some(Token::Bytes(data_bytes)) => data_bytes, _ => { - return Err(PaymentStatusErr::TxDeserializationError(ERRL!( + return Err(PaymentStatusErr::InvalidData(ERRL!( "Failed to decode HTLCParams from data_bytes" ))) }, }; - let htlc_params = match ethabi::decode(htlc_params(), data_bytes) { - Ok(htlc_params) => htlc_params, - Err(_) => { - return Err(PaymentStatusErr::TxDeserializationError(ERRL!( - "Failed to decode HTLCParams from data_bytes" - ))) - }, - }; + let htlc_params = + ethabi::decode(htlc_params(), data_bytes).map_err(|e| PaymentStatusErr::ABIError(ERRL!("{}", e)))?; let state = self .payment_status_v2( @@ -479,20 +473,13 @@ fn decode_and_validate_htlc_params( let data_bytes = match decoded.get(index) { Some(Token::Bytes(bytes)) => bytes, _ => { - return MmError::err(HtlcParamsError::TxDeserializationError( + return MmError::err(HtlcParamsError::InvalidData( "Expected Bytes for HTLCParams data".to_string(), )) }, }; - let decoded_params = match ethabi::decode(htlc_params(), data_bytes) { - Ok(params) => params, - Err(_) => { - return MmError::err(HtlcParamsError::TxDeserializationError( - "Failed to decode HTLCParams from data_bytes".to_string(), - )) - }, - }; + let decoded_params = ethabi::decode(htlc_params(), data_bytes)?; let expected_taker_secret_hash = Token::FixedBytes(expected_params.taker_secret_hash.clone()); let expected_maker_secret_hash = Token::FixedBytes(expected_params.maker_secret_hash.clone()); diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 1d22edb526..8ca714a34f 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1507,11 +1507,9 @@ impl From for ValidateSwapV2TxError { impl From for ValidateSwapV2TxError { fn from(err: PaymentStatusErr) -> Self { match err { - PaymentStatusErr::ABIError(e) - | PaymentStatusErr::Internal(e) - | PaymentStatusErr::TxDeserializationError(e) => ValidateSwapV2TxError::Internal(e), + PaymentStatusErr::Internal(e) => ValidateSwapV2TxError::Internal(e), PaymentStatusErr::Transport(e) => ValidateSwapV2TxError::Rpc(e), - PaymentStatusErr::InvalidData(e) => ValidateSwapV2TxError::InvalidData(e), + PaymentStatusErr::ABIError(e) | PaymentStatusErr::InvalidData(e) => ValidateSwapV2TxError::InvalidData(e), } } } @@ -1883,7 +1881,7 @@ impl From for WaitForTakerPaymentSpendError { match e { PaymentStatusErr::ABIError(e) => Self::ABIError(e), PaymentStatusErr::Transport(e) => Self::Transport(e), - PaymentStatusErr::Internal(e) | PaymentStatusErr::TxDeserializationError(e) => Self::Internal(e), + PaymentStatusErr::Internal(e) => Self::Internal(e), PaymentStatusErr::InvalidData(e) => Self::InvalidData(e), } } From be41221c0d74aad3d8523109eebd51a9b13399bf Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 19 Aug 2024 21:27:05 +0700 Subject: [PATCH 211/233] remove "reuse refund_taker_funding_timelock_impl" clarification --- mm2src/coins/eth.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 93a32d3696..b05126a352 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7148,7 +7148,6 @@ impl TakerCoinSwapOpsV2 for EthCoin { self.taker_payment_approve(args).await } - // TODO lets reuse refund_taker_funding_timelock_impl inside this func? async fn refund_combined_taker_payment( &self, args: RefundTakerPaymentArgs<'_>, From 983ea4d7cf5aa3124d6896effad0284011b0636e Mon Sep 17 00:00:00 2001 From: laruh Date: Mon, 19 Aug 2024 21:30:21 +0700 Subject: [PATCH 212/233] review: change fn refund_taker_funding_timelock_impl name --- mm2src/coins/eth.rs | 4 ++-- mm2src/coins/eth/eth_swap_v2.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index b05126a352..f10a3359ae 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -7097,7 +7097,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { &self, args: RefundTakerPaymentArgs<'_>, ) -> Result { - self.refund_taker_funding_timelock_impl(args).await + self.refund_taker_payment_with_timelock_impl(args).await } async fn refund_taker_funding_secret( @@ -7152,7 +7152,7 @@ impl TakerCoinSwapOpsV2 for EthCoin { &self, args: RefundTakerPaymentArgs<'_>, ) -> Result { - self.refund_taker_funding_timelock_impl(args).await + self.refund_taker_payment_with_timelock_impl(args).await } /// Eth doesnt have preimages diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index 81b0ff8737..dda270b23f 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -255,7 +255,7 @@ impl EthCoin { Ok(approve_tx) } - pub(crate) async fn refund_taker_funding_timelock_impl( + pub(crate) async fn refund_taker_payment_with_timelock_impl( &self, args: RefundTakerPaymentArgs<'_>, ) -> Result { From 8e50c8f9c376a962ea92343f3ee33d2eb802ad22 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 20 Aug 2024 17:49:12 +0700 Subject: [PATCH 213/233] fix compile error --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 3f3b8ee8be..0a55854b95 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -413,7 +413,7 @@ fn global_nft_with_random_privkey( let build_policy = EthPrivKeyBuildPolicy::IguanaPrivKey(random_secp256k1_secret()); let node = EthNode { url: GETH_RPC_URL.to_string(), - gui_auth: false, + komodo_proxy: false, }; let platform_request = EthActivationV2Request { nodes: vec![node], @@ -534,7 +534,7 @@ fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, co let node = EthNode { url: SEPOLIA_RPC_URL.to_string(), - gui_auth: false, + komodo_proxy: false, }; let platform_request = EthActivationV2Request { nodes: vec![node], @@ -1598,7 +1598,7 @@ fn eth_coin_v2_activation_with_random_privkey( let build_policy = EthPrivKeyBuildPolicy::IguanaPrivKey(random_secp256k1_secret()); let node = EthNode { url: GETH_RPC_URL.to_string(), - gui_auth: false, + komodo_proxy: false, }; let platform_request = EthActivationV2Request { nodes: vec![node], From 1c635b4bd1579806e26c6e60a2f58320dd338382 Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 20 Aug 2024 19:31:25 +0700 Subject: [PATCH 214/233] fix eth docker tests: ensure_p2p_context before eth_coin_from_conf_and_request_v2 --- .../tests/docker_tests/eth_docker_tests.rs | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 0a55854b95..589db439f0 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -21,11 +21,14 @@ use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, C SpendPaymentArgs, SwapOps, SwapTxFeePolicy, SwapTxTypeWithSecretHash, TakerCoinSwapOpsV2, ToBytes, Transaction, TxPreimageWithSig, ValidateNftMakerPaymentArgs, ValidateTakerFundingArgs}; use common::{block_on, now_sec}; -use crypto::Secp256k1Secret; +use crypto::{CryptoCtx, Secp256k1Secret}; use ethcore_transaction::Action; use ethereum_types::U256; +use futures::channel::mpsc; use futures01::Future; use mm2_core::mm_ctx::MmArc; +use mm2_libp2p::behaviours::atomicdex::generate_ed25519_keypair; +use mm2_net::p2p::P2PContext; use mm2_number::{BigDecimal, BigUint}; use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, eth_sepolia_conf, nft_dev_conf, nft_sepolia_conf, sepolia_erc20_dev_conf}; @@ -399,6 +402,29 @@ pub enum TestNftType { Erc721 { token_id: u32 }, } +fn init_p2p_context(ctx: &MmArc) { + let (cmd_tx, _) = mpsc::channel(10); + + let p2p_key = { + let crypto_ctx = match CryptoCtx::from_ctx(ctx) { + Ok(crypto_ctx) => crypto_ctx, + Err(_) => CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase").unwrap(), + }; + let key = sha256(crypto_ctx.mm2_internal_privkey_slice()); + key.take() + }; + + let p2p_context = P2PContext::new(cmd_tx, generate_ed25519_keypair(p2p_key)); + p2p_context.store_to_mm_arc(ctx); +} + +fn ensure_p2p_context(ctx: &MmArc) { + let p2p_ctx_lock = ctx.p2p_ctx.lock().unwrap(); + if p2p_ctx_lock.is_none() { + init_p2p_context(ctx); + } +} + /// Generates a global NFT coin instance with a random private key and an initial 100 ETH balance. /// Optionally mints a specified NFT (either ERC721 or ERC1155) to the global NFT address, /// with details recorded in the `nfts_infos` field based on the provided `nft_type`. @@ -430,6 +456,7 @@ fn global_nft_with_random_privkey( gap_limit: None, }; + ensure_p2p_context(&MM_CTX1); let coin = block_on(eth_coin_from_conf_and_request_v2( &MM_CTX1, nft_ticker.as_str(), @@ -551,6 +578,7 @@ fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, co gap_limit: None, }; + ensure_p2p_context(ctx); let coin = block_on(eth_coin_from_conf_and_request_v2( ctx, ticker, @@ -1614,6 +1642,7 @@ fn eth_coin_v2_activation_with_random_privkey( path_to_address: Default::default(), gap_limit: None, }; + ensure_p2p_context(&MM_CTX1); let coin = block_on(eth_coin_from_conf_and_request_v2( &MM_CTX1, ticker, @@ -1823,7 +1852,7 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { } #[test] -fn send_approve_and_spend_eth() { +fn taker_send_approve_and_spend_eth() { // sepolia test let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, ð_sepolia_conf(), false); let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, ð_sepolia_conf(), false); @@ -1931,7 +1960,7 @@ fn send_approve_and_spend_eth() { } #[test] -fn send_approve_and_spend_erc20() { +fn taker_send_approve_and_spend_erc20() { // sepolia test thread::sleep(Duration::from_secs(9)); let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); From 6f3492069556398227adc7071867a869196e2f4a Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 20 Aug 2024 21:22:21 +0700 Subject: [PATCH 215/233] fix eth docker tests: init CryptoCtx for MM_CTX1 --- mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs | 8 ++++++-- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 5 +---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 5c3e22a2a9..c29851ae8e 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -24,7 +24,7 @@ use coins::utxo::{coin_daemon_data_dir, sat_from_big_decimal, zcash_params_path, UtxoAddressFormat, UtxoCoinFields, UtxoCommonOps}; use coins::{ConfirmPaymentInput, MarketCoinOps, Transaction}; use crypto::privkey::key_pair_from_seed; -use crypto::Secp256k1Secret; +use crypto::{CryptoCtx, Secp256k1Secret}; use ethabi::Token; use ethereum_types::{H160 as H160Eth, U256}; use futures::TryFutureExt; @@ -64,7 +64,11 @@ lazy_static! { /// This means that different instances of the same coin should have separate global nonce locks. /// Utilizing different `MmCtx` instances allows us to assign Maker and Taker coins to separate `CoinsCtx`. /// This approach addresses the `replacement transaction` issue, which occurs when different transactions share the same nonce. - pub static ref MM_CTX1: MmArc = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); + pub static ref MM_CTX1: MmArc = { + let ctx = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); + CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase").unwrap(); + ctx + }; pub static ref GETH_WEB3: Web3 = Web3::new(Http::new(GETH_RPC_URL).unwrap()); pub static ref SEPOLIA_WEB3: Web3 = Web3::new(Http::new(SEPOLIA_RPC_URL).unwrap()); // Mutex used to prevent nonce re-usage during funding addresses used in tests diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 589db439f0..b0b4ad2bec 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -406,10 +406,7 @@ fn init_p2p_context(ctx: &MmArc) { let (cmd_tx, _) = mpsc::channel(10); let p2p_key = { - let crypto_ctx = match CryptoCtx::from_ctx(ctx) { - Ok(crypto_ctx) => crypto_ctx, - Err(_) => CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase").unwrap(), - }; + let crypto_ctx = CryptoCtx::from_ctx(ctx).unwrap(); let key = sha256(crypto_ctx.mm2_internal_privkey_slice()); key.take() }; From 098e270c9b7a35f6c6279878f4728cdda780b91b Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 20 Aug 2024 22:18:52 +0700 Subject: [PATCH 216/233] fix eth docker tests: build mmctx for global Nft --- .../tests/docker_tests/eth_docker_tests.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index b0b4ad2bec..212cdab7da 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -26,7 +26,7 @@ use ethcore_transaction::Action; use ethereum_types::U256; use futures::channel::mpsc; use futures01::Future; -use mm2_core::mm_ctx::MmArc; +use mm2_core::mm_ctx::{MmArc, MmCtxBuilder}; use mm2_libp2p::behaviours::atomicdex::generate_ed25519_keypair; use mm2_net::p2p::P2PContext; use mm2_number::{BigDecimal, BigUint}; @@ -406,7 +406,10 @@ fn init_p2p_context(ctx: &MmArc) { let (cmd_tx, _) = mpsc::channel(10); let p2p_key = { - let crypto_ctx = CryptoCtx::from_ctx(ctx).unwrap(); + let crypto_ctx = match CryptoCtx::from_ctx(ctx) { + Ok(crypto_ctx) => crypto_ctx, + Err(_) => CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase").unwrap(), + }; let key = sha256(crypto_ctx.mm2_internal_privkey_slice()); key.take() }; @@ -452,10 +455,14 @@ fn global_nft_with_random_privkey( path_to_address: Default::default(), gap_limit: None, }; - - ensure_p2p_context(&MM_CTX1); + let ctx = MmCtxBuilder::new() + .with_conf(json!({"use_trading_proto_v2": true})) + .into_mm_arc(); + ctx.init_metrics().unwrap(); + CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase").unwrap(); + ensure_p2p_context(&ctx); let coin = block_on(eth_coin_from_conf_and_request_v2( - &MM_CTX1, + &ctx, nft_ticker.as_str(), &nft_dev_conf(), platform_request, @@ -1639,7 +1646,6 @@ fn eth_coin_v2_activation_with_random_privkey( path_to_address: Default::default(), gap_limit: None, }; - ensure_p2p_context(&MM_CTX1); let coin = block_on(eth_coin_from_conf_and_request_v2( &MM_CTX1, ticker, From 8469afff6ea3af117654cb6b0606eb61133d1a21 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 21 Aug 2024 12:33:50 +0700 Subject: [PATCH 217/233] fix eth docker tests: init_p2p_context right in lazy static --- .../tests/docker_tests/docker_tests_common.rs | 11 +++++++--- .../tests/docker_tests/eth_docker_tests.rs | 20 +++++-------------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index c29851ae8e..6e65e5b2d4 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -8,7 +8,7 @@ pub use mm2_test_helpers::for_tests::{check_my_swap_status, check_recent_swaps, TAKER_SUCCESS_EVENTS}; use super::eth_docker_tests::{erc20_contract_checksum, fill_eth, fill_eth_erc20_with_private_key, geth_account, - swap_contract}; + init_p2p_context, swap_contract}; use bitcrypto::{dhash160, ChecksumType}; use chain::TransactionOutput; use coins::eth::addr_from_raw_pubkey; @@ -58,7 +58,12 @@ lazy_static! { // Due to the SLP protocol limitations only 19 outputs (18 + change) can be sent in one transaction, which is sufficient for now though. // Supply more privkeys when 18 will be not enough. pub static ref SLP_TOKEN_OWNERS: Mutex> = Mutex::new(Vec::with_capacity(18)); - pub static ref MM_CTX: MmArc = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); + pub static ref MM_CTX: MmArc = { + let ctx = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); + CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase").unwrap(); + init_p2p_context(&ctx); + ctx + }; /// We need a second `MmCtx` instance when we use the same private keys for Maker and Taker across various tests. /// When enabling coins for both Maker and Taker, two distinct coin instances are created. /// This means that different instances of the same coin should have separate global nonce locks. @@ -66,7 +71,7 @@ lazy_static! { /// This approach addresses the `replacement transaction` issue, which occurs when different transactions share the same nonce. pub static ref MM_CTX1: MmArc = { let ctx = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); - CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase").unwrap(); + CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase1").unwrap(); ctx }; pub static ref GETH_WEB3: Web3 = Web3::new(Http::new(GETH_RPC_URL).unwrap()); diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 212cdab7da..3bb12be0e5 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -26,7 +26,7 @@ use ethcore_transaction::Action; use ethereum_types::U256; use futures::channel::mpsc; use futures01::Future; -use mm2_core::mm_ctx::{MmArc, MmCtxBuilder}; +use mm2_core::mm_ctx::MmArc; use mm2_libp2p::behaviours::atomicdex::generate_ed25519_keypair; use mm2_net::p2p::P2PContext; use mm2_number::{BigDecimal, BigUint}; @@ -402,14 +402,11 @@ pub enum TestNftType { Erc721 { token_id: u32 }, } -fn init_p2p_context(ctx: &MmArc) { +pub(crate) fn init_p2p_context(ctx: &MmArc) { let (cmd_tx, _) = mpsc::channel(10); let p2p_key = { - let crypto_ctx = match CryptoCtx::from_ctx(ctx) { - Ok(crypto_ctx) => crypto_ctx, - Err(_) => CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase").unwrap(), - }; + let crypto_ctx = CryptoCtx::from_ctx(ctx).unwrap(); let key = sha256(crypto_ctx.mm2_internal_privkey_slice()); key.take() }; @@ -418,6 +415,7 @@ fn init_p2p_context(ctx: &MmArc) { p2p_context.store_to_mm_arc(ctx); } +#[allow(dead_code)] fn ensure_p2p_context(ctx: &MmArc) { let p2p_ctx_lock = ctx.p2p_ctx.lock().unwrap(); if p2p_ctx_lock.is_none() { @@ -455,14 +453,8 @@ fn global_nft_with_random_privkey( path_to_address: Default::default(), gap_limit: None, }; - let ctx = MmCtxBuilder::new() - .with_conf(json!({"use_trading_proto_v2": true})) - .into_mm_arc(); - ctx.init_metrics().unwrap(); - CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase").unwrap(); - ensure_p2p_context(&ctx); let coin = block_on(eth_coin_from_conf_and_request_v2( - &ctx, + &MM_CTX1, nft_ticker.as_str(), &nft_dev_conf(), platform_request, @@ -581,8 +573,6 @@ fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, co path_to_address: Default::default(), gap_limit: None, }; - - ensure_p2p_context(ctx); let coin = block_on(eth_coin_from_conf_and_request_v2( ctx, ticker, From 98f78d292eaae33401880c95d2ddd5b41119be6f Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 21 Aug 2024 13:18:56 +0700 Subject: [PATCH 218/233] fix eth docker tests: use ensure_p2p_context --- .../tests/docker_tests/docker_tests_common.rs | 17 ++++------------- .../tests/docker_tests/eth_docker_tests.rs | 9 +++++++-- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 6e65e5b2d4..5c3e22a2a9 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -8,7 +8,7 @@ pub use mm2_test_helpers::for_tests::{check_my_swap_status, check_recent_swaps, TAKER_SUCCESS_EVENTS}; use super::eth_docker_tests::{erc20_contract_checksum, fill_eth, fill_eth_erc20_with_private_key, geth_account, - init_p2p_context, swap_contract}; + swap_contract}; use bitcrypto::{dhash160, ChecksumType}; use chain::TransactionOutput; use coins::eth::addr_from_raw_pubkey; @@ -24,7 +24,7 @@ use coins::utxo::{coin_daemon_data_dir, sat_from_big_decimal, zcash_params_path, UtxoAddressFormat, UtxoCoinFields, UtxoCommonOps}; use coins::{ConfirmPaymentInput, MarketCoinOps, Transaction}; use crypto::privkey::key_pair_from_seed; -use crypto::{CryptoCtx, Secp256k1Secret}; +use crypto::Secp256k1Secret; use ethabi::Token; use ethereum_types::{H160 as H160Eth, U256}; use futures::TryFutureExt; @@ -58,22 +58,13 @@ lazy_static! { // Due to the SLP protocol limitations only 19 outputs (18 + change) can be sent in one transaction, which is sufficient for now though. // Supply more privkeys when 18 will be not enough. pub static ref SLP_TOKEN_OWNERS: Mutex> = Mutex::new(Vec::with_capacity(18)); - pub static ref MM_CTX: MmArc = { - let ctx = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); - CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase").unwrap(); - init_p2p_context(&ctx); - ctx - }; + pub static ref MM_CTX: MmArc = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); /// We need a second `MmCtx` instance when we use the same private keys for Maker and Taker across various tests. /// When enabling coins for both Maker and Taker, two distinct coin instances are created. /// This means that different instances of the same coin should have separate global nonce locks. /// Utilizing different `MmCtx` instances allows us to assign Maker and Taker coins to separate `CoinsCtx`. /// This approach addresses the `replacement transaction` issue, which occurs when different transactions share the same nonce. - pub static ref MM_CTX1: MmArc = { - let ctx = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); - CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase1").unwrap(); - ctx - }; + pub static ref MM_CTX1: MmArc = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); pub static ref GETH_WEB3: Web3 = Web3::new(Http::new(GETH_RPC_URL).unwrap()); pub static ref SEPOLIA_WEB3: Web3 = Web3::new(Http::new(SEPOLIA_RPC_URL).unwrap()); // Mutex used to prevent nonce re-usage during funding addresses used in tests diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 3bb12be0e5..d851fbcb36 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -403,10 +403,13 @@ pub enum TestNftType { } pub(crate) fn init_p2p_context(ctx: &MmArc) { - let (cmd_tx, _) = mpsc::channel(10); + let (cmd_tx, _) = mpsc::channel(512); let p2p_key = { - let crypto_ctx = CryptoCtx::from_ctx(ctx).unwrap(); + let crypto_ctx = match CryptoCtx::from_ctx(ctx) { + Ok(crypto_ctx) => crypto_ctx, + Err(_) => CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase").unwrap(), + }; let key = sha256(crypto_ctx.mm2_internal_privkey_slice()); key.take() }; @@ -453,6 +456,7 @@ fn global_nft_with_random_privkey( path_to_address: Default::default(), gap_limit: None, }; + ensure_p2p_context(&MM_CTX1); let coin = block_on(eth_coin_from_conf_and_request_v2( &MM_CTX1, nft_ticker.as_str(), @@ -573,6 +577,7 @@ fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, co path_to_address: Default::default(), gap_limit: None, }; + ensure_p2p_context(ctx); let coin = block_on(eth_coin_from_conf_and_request_v2( ctx, ticker, From 885c0e9bea774570b83ef3e26eaed547ea5a08c6 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 21 Aug 2024 13:46:25 +0700 Subject: [PATCH 219/233] comment for_slp_ops.wait_ready --- mm2src/mm2_main/tests/docker_tests_main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests_main.rs b/mm2src/mm2_main/tests/docker_tests_main.rs index 5225f1b029..df0f6868ae 100644 --- a/mm2src/mm2_main/tests/docker_tests_main.rs +++ b/mm2src/mm2_main/tests/docker_tests_main.rs @@ -79,12 +79,12 @@ pub fn docker_tests_runner(tests: &[&TestDescAndFn]) { let utxo_ops = UtxoAssetDockerOps::from_ticker("MYCOIN"); let utxo_ops1 = UtxoAssetDockerOps::from_ticker("MYCOIN1"); let qtum_ops = QtumDockerOps::new(); - let for_slp_ops = BchDockerOps::from_ticker("FORSLP"); + // let for_slp_ops = BchDockerOps::from_ticker("FORSLP"); qtum_ops.wait_ready(2); qtum_ops.initialize_contracts(); - for_slp_ops.wait_ready(4); - for_slp_ops.initialize_slp(); + // for_slp_ops.wait_ready(4); + // for_slp_ops.initialize_slp(); utxo_ops.wait_ready(4); utxo_ops1.wait_ready(4); From 525b99dea937ff9b8463603c06b1e6d1ce36a55d Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 21 Aug 2024 13:57:54 +0700 Subject: [PATCH 220/233] Revert "comment for_slp_ops.wait_ready" This reverts commit 885c0e9bea774570b83ef3e26eaed547ea5a08c6. --- mm2src/mm2_main/tests/docker_tests_main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests_main.rs b/mm2src/mm2_main/tests/docker_tests_main.rs index df0f6868ae..5225f1b029 100644 --- a/mm2src/mm2_main/tests/docker_tests_main.rs +++ b/mm2src/mm2_main/tests/docker_tests_main.rs @@ -79,12 +79,12 @@ pub fn docker_tests_runner(tests: &[&TestDescAndFn]) { let utxo_ops = UtxoAssetDockerOps::from_ticker("MYCOIN"); let utxo_ops1 = UtxoAssetDockerOps::from_ticker("MYCOIN1"); let qtum_ops = QtumDockerOps::new(); - // let for_slp_ops = BchDockerOps::from_ticker("FORSLP"); + let for_slp_ops = BchDockerOps::from_ticker("FORSLP"); qtum_ops.wait_ready(2); qtum_ops.initialize_contracts(); - // for_slp_ops.wait_ready(4); - // for_slp_ops.initialize_slp(); + for_slp_ops.wait_ready(4); + for_slp_ops.initialize_slp(); utxo_ops.wait_ready(4); utxo_ops1.wait_ready(4); From 0e3589814a06352ec86db242b5e42396eb47d7ba Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 21 Aug 2024 15:45:42 +0700 Subject: [PATCH 221/233] docker tests: init_p2p_context in lazy static --- .../tests/docker_tests/docker_tests_common.rs | 14 +++++++++++--- .../tests/docker_tests/eth_docker_tests.rs | 2 -- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 5c3e22a2a9..dd030e3c25 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -8,7 +8,7 @@ pub use mm2_test_helpers::for_tests::{check_my_swap_status, check_recent_swaps, TAKER_SUCCESS_EVENTS}; use super::eth_docker_tests::{erc20_contract_checksum, fill_eth, fill_eth_erc20_with_private_key, geth_account, - swap_contract}; + init_p2p_context, swap_contract}; use bitcrypto::{dhash160, ChecksumType}; use chain::TransactionOutput; use coins::eth::addr_from_raw_pubkey; @@ -58,13 +58,21 @@ lazy_static! { // Due to the SLP protocol limitations only 19 outputs (18 + change) can be sent in one transaction, which is sufficient for now though. // Supply more privkeys when 18 will be not enough. pub static ref SLP_TOKEN_OWNERS: Mutex> = Mutex::new(Vec::with_capacity(18)); - pub static ref MM_CTX: MmArc = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); + pub static ref MM_CTX: MmArc = { + let ctx = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); + init_p2p_context(&ctx); + ctx + }; /// We need a second `MmCtx` instance when we use the same private keys for Maker and Taker across various tests. /// When enabling coins for both Maker and Taker, two distinct coin instances are created. /// This means that different instances of the same coin should have separate global nonce locks. /// Utilizing different `MmCtx` instances allows us to assign Maker and Taker coins to separate `CoinsCtx`. /// This approach addresses the `replacement transaction` issue, which occurs when different transactions share the same nonce. - pub static ref MM_CTX1: MmArc = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); + pub static ref MM_CTX1: MmArc = { + let ctx = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); + init_p2p_context(&ctx); + ctx + }; pub static ref GETH_WEB3: Web3 = Web3::new(Http::new(GETH_RPC_URL).unwrap()); pub static ref SEPOLIA_WEB3: Web3 = Web3::new(Http::new(SEPOLIA_RPC_URL).unwrap()); // Mutex used to prevent nonce re-usage during funding addresses used in tests diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index d851fbcb36..f850a4780a 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -456,7 +456,6 @@ fn global_nft_with_random_privkey( path_to_address: Default::default(), gap_limit: None, }; - ensure_p2p_context(&MM_CTX1); let coin = block_on(eth_coin_from_conf_and_request_v2( &MM_CTX1, nft_ticker.as_str(), @@ -577,7 +576,6 @@ fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, co path_to_address: Default::default(), gap_limit: None, }; - ensure_p2p_context(ctx); let coin = block_on(eth_coin_from_conf_and_request_v2( ctx, ticker, From fbdbf10677ac0d4a987a06231d8274215b407049 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 22 Aug 2024 15:04:00 +0700 Subject: [PATCH 222/233] docker tests: exclude p2pctx in build_web3_instances for tests --- mm2src/coins/eth/v2_activation.rs | 14 +++++++-- .../eth/web3_transport/http_transport.rs | 1 + .../tests/docker_tests/docker_tests_common.rs | 14 ++------- .../tests/docker_tests/eth_docker_tests.rs | 29 +------------------ 4 files changed, 17 insertions(+), 41 deletions(-) diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index dffa0a4e17..9827a70e80 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -796,6 +796,7 @@ async fn build_web3_instances( let event_handlers = rpc_event_handlers_for_eth_transport(ctx, coin_ticker.clone()); + #[cfg(not(test))] let p2p_ctx = P2PContext::fetch_from_mm_arc(ctx); let mut web3_instances = Vec::with_capacity(eth_nodes.len()); for eth_node in eth_nodes { @@ -810,12 +811,16 @@ async fn build_web3_instances( let node = WebsocketTransportNode { uri: uri.clone() }; + #[cfg(not(test))] let mut websocket_transport = WebsocketTransport::with_event_handlers(node, event_handlers.clone()); - + #[cfg(not(test))] if eth_node.komodo_proxy { websocket_transport.proxy_sign_keypair = Some(p2p_ctx.keypair().clone()); } + #[cfg(test)] + let websocket_transport = WebsocketTransport::with_event_handlers(node, event_handlers.clone()); + // Temporarily start the connection loop (we close the connection once we have the client version below). // Ideally, it would be much better to not do this workaround, which requires a lot of refactoring or // dropping websocket support on parity nodes. @@ -833,13 +838,18 @@ async fn build_web3_instances( komodo_proxy: eth_node.komodo_proxy, }; + #[cfg(not(test))] let komodo_proxy = node.komodo_proxy; + #[cfg(not(test))] let mut http_transport = HttpTransport::with_event_handlers(node, event_handlers.clone()); - + #[cfg(not(test))] if komodo_proxy { http_transport.proxy_sign_keypair = Some(p2p_ctx.keypair().clone()); } + #[cfg(test)] + let http_transport = HttpTransport::with_event_handlers(node, event_handlers.clone()); + Web3Transport::from(http_transport) }, _ => { diff --git a/mm2src/coins/eth/web3_transport/http_transport.rs b/mm2src/coins/eth/web3_transport/http_transport.rs index 5d6ad98a26..616ce79eca 100644 --- a/mm2src/coins/eth/web3_transport/http_transport.rs +++ b/mm2src/coins/eth/web3_transport/http_transport.rs @@ -46,6 +46,7 @@ pub struct HttpTransport { #[derive(Clone, Debug)] pub struct HttpTransportNode { pub(crate) uri: http::Uri, + #[cfg_attr(test, allow(dead_code))] pub(crate) komodo_proxy: bool, } diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index dd030e3c25..5c3e22a2a9 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -8,7 +8,7 @@ pub use mm2_test_helpers::for_tests::{check_my_swap_status, check_recent_swaps, TAKER_SUCCESS_EVENTS}; use super::eth_docker_tests::{erc20_contract_checksum, fill_eth, fill_eth_erc20_with_private_key, geth_account, - init_p2p_context, swap_contract}; + swap_contract}; use bitcrypto::{dhash160, ChecksumType}; use chain::TransactionOutput; use coins::eth::addr_from_raw_pubkey; @@ -58,21 +58,13 @@ lazy_static! { // Due to the SLP protocol limitations only 19 outputs (18 + change) can be sent in one transaction, which is sufficient for now though. // Supply more privkeys when 18 will be not enough. pub static ref SLP_TOKEN_OWNERS: Mutex> = Mutex::new(Vec::with_capacity(18)); - pub static ref MM_CTX: MmArc = { - let ctx = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); - init_p2p_context(&ctx); - ctx - }; + pub static ref MM_CTX: MmArc = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); /// We need a second `MmCtx` instance when we use the same private keys for Maker and Taker across various tests. /// When enabling coins for both Maker and Taker, two distinct coin instances are created. /// This means that different instances of the same coin should have separate global nonce locks. /// Utilizing different `MmCtx` instances allows us to assign Maker and Taker coins to separate `CoinsCtx`. /// This approach addresses the `replacement transaction` issue, which occurs when different transactions share the same nonce. - pub static ref MM_CTX1: MmArc = { - let ctx = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); - init_p2p_context(&ctx); - ctx - }; + pub static ref MM_CTX1: MmArc = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); pub static ref GETH_WEB3: Web3 = Web3::new(Http::new(GETH_RPC_URL).unwrap()); pub static ref SEPOLIA_WEB3: Web3 = Web3::new(Http::new(SEPOLIA_RPC_URL).unwrap()); // Mutex used to prevent nonce re-usage during funding addresses used in tests diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index f850a4780a..503a497c56 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -21,14 +21,11 @@ use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, C SpendPaymentArgs, SwapOps, SwapTxFeePolicy, SwapTxTypeWithSecretHash, TakerCoinSwapOpsV2, ToBytes, Transaction, TxPreimageWithSig, ValidateNftMakerPaymentArgs, ValidateTakerFundingArgs}; use common::{block_on, now_sec}; -use crypto::{CryptoCtx, Secp256k1Secret}; +use crypto::Secp256k1Secret; use ethcore_transaction::Action; use ethereum_types::U256; -use futures::channel::mpsc; use futures01::Future; use mm2_core::mm_ctx::MmArc; -use mm2_libp2p::behaviours::atomicdex::generate_ed25519_keypair; -use mm2_net::p2p::P2PContext; use mm2_number::{BigDecimal, BigUint}; use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, eth_sepolia_conf, nft_dev_conf, nft_sepolia_conf, sepolia_erc20_dev_conf}; @@ -402,30 +399,6 @@ pub enum TestNftType { Erc721 { token_id: u32 }, } -pub(crate) fn init_p2p_context(ctx: &MmArc) { - let (cmd_tx, _) = mpsc::channel(512); - - let p2p_key = { - let crypto_ctx = match CryptoCtx::from_ctx(ctx) { - Ok(crypto_ctx) => crypto_ctx, - Err(_) => CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase").unwrap(), - }; - let key = sha256(crypto_ctx.mm2_internal_privkey_slice()); - key.take() - }; - - let p2p_context = P2PContext::new(cmd_tx, generate_ed25519_keypair(p2p_key)); - p2p_context.store_to_mm_arc(ctx); -} - -#[allow(dead_code)] -fn ensure_p2p_context(ctx: &MmArc) { - let p2p_ctx_lock = ctx.p2p_ctx.lock().unwrap(); - if p2p_ctx_lock.is_none() { - init_p2p_context(ctx); - } -} - /// Generates a global NFT coin instance with a random private key and an initial 100 ETH balance. /// Optionally mints a specified NFT (either ERC721 or ERC1155) to the global NFT address, /// with details recorded in the `nfts_infos` field based on the provided `nft_type`. From eb83c70cca880d35e5df58bb86ed628c2ae0ac08 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 22 Aug 2024 18:45:26 +0700 Subject: [PATCH 223/233] Revert "docker tests: exclude p2pctx in build_web3_instances for tests" This reverts commit fbdbf10677ac0d4a987a06231d8274215b407049. --- mm2src/coins/eth/v2_activation.rs | 14 ++------- .../eth/web3_transport/http_transport.rs | 1 - .../tests/docker_tests/docker_tests_common.rs | 14 +++++++-- .../tests/docker_tests/eth_docker_tests.rs | 29 ++++++++++++++++++- 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 9827a70e80..dffa0a4e17 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -796,7 +796,6 @@ async fn build_web3_instances( let event_handlers = rpc_event_handlers_for_eth_transport(ctx, coin_ticker.clone()); - #[cfg(not(test))] let p2p_ctx = P2PContext::fetch_from_mm_arc(ctx); let mut web3_instances = Vec::with_capacity(eth_nodes.len()); for eth_node in eth_nodes { @@ -811,16 +810,12 @@ async fn build_web3_instances( let node = WebsocketTransportNode { uri: uri.clone() }; - #[cfg(not(test))] let mut websocket_transport = WebsocketTransport::with_event_handlers(node, event_handlers.clone()); - #[cfg(not(test))] + if eth_node.komodo_proxy { websocket_transport.proxy_sign_keypair = Some(p2p_ctx.keypair().clone()); } - #[cfg(test)] - let websocket_transport = WebsocketTransport::with_event_handlers(node, event_handlers.clone()); - // Temporarily start the connection loop (we close the connection once we have the client version below). // Ideally, it would be much better to not do this workaround, which requires a lot of refactoring or // dropping websocket support on parity nodes. @@ -838,18 +833,13 @@ async fn build_web3_instances( komodo_proxy: eth_node.komodo_proxy, }; - #[cfg(not(test))] let komodo_proxy = node.komodo_proxy; - #[cfg(not(test))] let mut http_transport = HttpTransport::with_event_handlers(node, event_handlers.clone()); - #[cfg(not(test))] + if komodo_proxy { http_transport.proxy_sign_keypair = Some(p2p_ctx.keypair().clone()); } - #[cfg(test)] - let http_transport = HttpTransport::with_event_handlers(node, event_handlers.clone()); - Web3Transport::from(http_transport) }, _ => { diff --git a/mm2src/coins/eth/web3_transport/http_transport.rs b/mm2src/coins/eth/web3_transport/http_transport.rs index 616ce79eca..5d6ad98a26 100644 --- a/mm2src/coins/eth/web3_transport/http_transport.rs +++ b/mm2src/coins/eth/web3_transport/http_transport.rs @@ -46,7 +46,6 @@ pub struct HttpTransport { #[derive(Clone, Debug)] pub struct HttpTransportNode { pub(crate) uri: http::Uri, - #[cfg_attr(test, allow(dead_code))] pub(crate) komodo_proxy: bool, } diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 5c3e22a2a9..dd030e3c25 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -8,7 +8,7 @@ pub use mm2_test_helpers::for_tests::{check_my_swap_status, check_recent_swaps, TAKER_SUCCESS_EVENTS}; use super::eth_docker_tests::{erc20_contract_checksum, fill_eth, fill_eth_erc20_with_private_key, geth_account, - swap_contract}; + init_p2p_context, swap_contract}; use bitcrypto::{dhash160, ChecksumType}; use chain::TransactionOutput; use coins::eth::addr_from_raw_pubkey; @@ -58,13 +58,21 @@ lazy_static! { // Due to the SLP protocol limitations only 19 outputs (18 + change) can be sent in one transaction, which is sufficient for now though. // Supply more privkeys when 18 will be not enough. pub static ref SLP_TOKEN_OWNERS: Mutex> = Mutex::new(Vec::with_capacity(18)); - pub static ref MM_CTX: MmArc = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); + pub static ref MM_CTX: MmArc = { + let ctx = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); + init_p2p_context(&ctx); + ctx + }; /// We need a second `MmCtx` instance when we use the same private keys for Maker and Taker across various tests. /// When enabling coins for both Maker and Taker, two distinct coin instances are created. /// This means that different instances of the same coin should have separate global nonce locks. /// Utilizing different `MmCtx` instances allows us to assign Maker and Taker coins to separate `CoinsCtx`. /// This approach addresses the `replacement transaction` issue, which occurs when different transactions share the same nonce. - pub static ref MM_CTX1: MmArc = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); + pub static ref MM_CTX1: MmArc = { + let ctx = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); + init_p2p_context(&ctx); + ctx + }; pub static ref GETH_WEB3: Web3 = Web3::new(Http::new(GETH_RPC_URL).unwrap()); pub static ref SEPOLIA_WEB3: Web3 = Web3::new(Http::new(SEPOLIA_RPC_URL).unwrap()); // Mutex used to prevent nonce re-usage during funding addresses used in tests diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 503a497c56..f850a4780a 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -21,11 +21,14 @@ use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, C SpendPaymentArgs, SwapOps, SwapTxFeePolicy, SwapTxTypeWithSecretHash, TakerCoinSwapOpsV2, ToBytes, Transaction, TxPreimageWithSig, ValidateNftMakerPaymentArgs, ValidateTakerFundingArgs}; use common::{block_on, now_sec}; -use crypto::Secp256k1Secret; +use crypto::{CryptoCtx, Secp256k1Secret}; use ethcore_transaction::Action; use ethereum_types::U256; +use futures::channel::mpsc; use futures01::Future; use mm2_core::mm_ctx::MmArc; +use mm2_libp2p::behaviours::atomicdex::generate_ed25519_keypair; +use mm2_net::p2p::P2PContext; use mm2_number::{BigDecimal, BigUint}; use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, eth_sepolia_conf, nft_dev_conf, nft_sepolia_conf, sepolia_erc20_dev_conf}; @@ -399,6 +402,30 @@ pub enum TestNftType { Erc721 { token_id: u32 }, } +pub(crate) fn init_p2p_context(ctx: &MmArc) { + let (cmd_tx, _) = mpsc::channel(512); + + let p2p_key = { + let crypto_ctx = match CryptoCtx::from_ctx(ctx) { + Ok(crypto_ctx) => crypto_ctx, + Err(_) => CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase").unwrap(), + }; + let key = sha256(crypto_ctx.mm2_internal_privkey_slice()); + key.take() + }; + + let p2p_context = P2PContext::new(cmd_tx, generate_ed25519_keypair(p2p_key)); + p2p_context.store_to_mm_arc(ctx); +} + +#[allow(dead_code)] +fn ensure_p2p_context(ctx: &MmArc) { + let p2p_ctx_lock = ctx.p2p_ctx.lock().unwrap(); + if p2p_ctx_lock.is_none() { + init_p2p_context(ctx); + } +} + /// Generates a global NFT coin instance with a random private key and an initial 100 ETH balance. /// Optionally mints a specified NFT (either ERC721 or ERC1155) to the global NFT address, /// with details recorded in the `nfts_infos` field based on the provided `nft_type`. From f7668cef9591c010114344f68fd49d24dd29ac04 Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 22 Aug 2024 19:23:49 +0700 Subject: [PATCH 224/233] docker tests: provide build_web3_instances_for_test and eth_coin_from_conf_and_request_v2_for_test functions --- mm2src/coins/eth/v2_activation.rs | 206 ++++++++++++++++++ .../tests/docker_tests/eth_docker_tests.rs | 8 +- 2 files changed, 210 insertions(+), 4 deletions(-) diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index dffa0a4e17..6d37ee0912 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -937,3 +937,209 @@ fn compress_public_key(uncompressed: H520) -> MmResult MmResult { + if req.swap_contract_address == Address::default() { + return Err(EthActivationV2Error::InvalidSwapContractAddr( + "swap_contract_address can't be zero address".to_string(), + ) + .into()); + } + + if ctx.use_trading_proto_v2() { + let contracts = req.swap_v2_contracts.as_ref().ok_or_else(|| { + EthActivationV2Error::InvalidPayload( + "swap_v2_contracts must be provided when using trading protocol v2".to_string(), + ) + })?; + if contracts.maker_swap_v2_contract == Address::default() + || contracts.taker_swap_v2_contract == Address::default() + || contracts.nft_maker_swap_v2_contract == Address::default() + { + return Err(EthActivationV2Error::InvalidSwapContractAddr( + "All swap_v2_contracts addresses must be non-zero".to_string(), + ) + .into()); + } + } + + if let Some(fallback) = req.fallback_swap_contract { + if fallback == Address::default() { + return Err(EthActivationV2Error::InvalidFallbackSwapContract( + "fallback_swap_contract can't be zero address".to_string(), + ) + .into()); + } + } + + let (priv_key_policy, derivation_method) = build_address_and_priv_key_policy( + ctx, + ticker, + conf, + priv_key_build_policy, + &req.path_to_address, + req.gap_limit, + ) + .await?; + + let chain_id = conf["chain_id"].as_u64().ok_or(EthActivationV2Error::ChainIdNotSet)?; + let web3_instances = match (req.rpc_mode, &priv_key_policy) { + (EthRpcMode::Default, EthPrivKeyPolicy::Iguana(_) | EthPrivKeyPolicy::HDWallet { .. }) + | (EthRpcMode::Default, EthPrivKeyPolicy::Trezor) => { + build_web3_instances_for_test(ctx, ticker.to_string(), req.nodes.clone()).await? + }, + }; + + let required_confirmations = req + .required_confirmations + .unwrap_or_else(|| { + conf["required_confirmations"] + .as_u64() + .unwrap_or(DEFAULT_REQUIRED_CONFIRMATIONS as u64) + }) + .into(); + + let sign_message_prefix: Option = json::from_value(conf["sign_message_prefix"].clone()).ok(); + + let trezor_coin: Option = json::from_value(conf["trezor_coin"].clone()).ok(); + + let address_nonce_locks = { + let mut map = NONCE_LOCK.lock().unwrap(); + Arc::new(AsyncMutex::new( + map.entry(ticker.to_string()).or_insert_with(new_nonce_lock).clone(), + )) + }; + + let abortable_system = ctx.abortable_system.create_subsystem()?; + let coin_type = EthCoinType::Eth; + let platform_fee_estimator_state = FeeEstimatorState::init_fee_estimator(ctx, conf, &coin_type).await?; + let max_eth_tx_type = get_max_eth_tx_type_conf(ctx, conf, &coin_type).await?; + let gas_limit = extract_gas_limit_from_conf(conf) + .map_to_mm(|e| EthActivationV2Error::InternalError(format!("invalid gas_limit config {}", e)))?; + + let coin = EthCoinImpl { + priv_key_policy, + derivation_method: Arc::new(derivation_method), + coin_type, + sign_message_prefix, + swap_contract_address: req.swap_contract_address, + swap_v2_contracts: req.swap_v2_contracts, + fallback_swap_contract: req.fallback_swap_contract, + contract_supports_watchers: req.contract_supports_watchers, + decimals: ETH_DECIMALS, + ticker: ticker.to_string(), + web3_instances: AsyncMutex::new(web3_instances), + history_sync_state: Mutex::new(HistorySyncState::NotEnabled), + swap_txfee_policy: Mutex::new(SwapTxFeePolicy::Internal), + max_eth_tx_type, + ctx: ctx.weak(), + required_confirmations, + chain_id, + trezor_coin, + logs_block_range: conf["logs_block_range"].as_u64().unwrap_or(DEFAULT_LOGS_BLOCK_RANGE), + address_nonce_locks, + erc20_tokens_infos: Default::default(), + nfts_infos: Default::default(), + platform_fee_estimator_state, + gas_limit, + abortable_system, + }; + + let coin = EthCoin(Arc::new(coin)); + coin.spawn_balance_stream_if_enabled(ctx) + .await + .map_err(EthActivationV2Error::FailedSpawningBalanceEvents)?; + + Ok(coin) +} + +/// Builds web3 instances without using [P2PContext] +#[cfg(all(feature = "for-tests", not(target_arch = "wasm32")))] +async fn build_web3_instances_for_test( + ctx: &MmArc, + coin_ticker: String, + mut eth_nodes: Vec, +) -> MmResult, EthActivationV2Error> { + if eth_nodes.is_empty() { + return MmError::err(EthActivationV2Error::AtLeastOneNodeRequired); + } + + let mut rng = small_rng(); + eth_nodes.as_mut_slice().shuffle(&mut rng); + drop_mutability!(eth_nodes); + + let event_handlers = rpc_event_handlers_for_eth_transport(ctx, coin_ticker.clone()); + + let mut web3_instances = Vec::with_capacity(eth_nodes.len()); + for eth_node in eth_nodes { + let uri: Uri = eth_node + .url + .parse() + .map_err(|_| EthActivationV2Error::InvalidPayload(format!("{} could not be parsed.", eth_node.url)))?; + + let transport = match uri.scheme_str() { + Some("ws") | Some("wss") => { + const TMP_SOCKET_CONNECTION: Duration = Duration::from_secs(20); + let node = WebsocketTransportNode { uri: uri.clone() }; + let websocket_transport = WebsocketTransport::with_event_handlers(node, event_handlers.clone()); + + // Temporarily start the connection loop (we close the connection once we have the client version below). + // Ideally, it would be much better to not do this workaround, which requires a lot of refactoring or + // dropping websocket support on parity nodes. + let fut = websocket_transport + .clone() + .start_connection_loop(Some(Instant::now() + TMP_SOCKET_CONNECTION)); + let settings = AbortSettings::info_on_abort(format!("connection loop stopped for {:?}", uri)); + ctx.spawner().spawn_with_settings(fut, settings); + + Web3Transport::Websocket(websocket_transport) + }, + Some("http") | Some("https") => { + let node = HttpTransportNode { + uri, + komodo_proxy: eth_node.komodo_proxy, + }; + + let http_transport = HttpTransport::with_event_handlers(node, event_handlers.clone()); + + Web3Transport::from(http_transport) + }, + _ => { + return MmError::err(EthActivationV2Error::InvalidPayload(format!( + "Invalid node address '{uri}'. Only http(s) and ws(s) nodes are supported" + ))); + }, + }; + + let web3 = Web3::new(transport); + let version = match web3.web3().client_version().await { + Ok(v) => v, + Err(e) => { + error!("Couldn't get client version for url {}: {}", eth_node.url, e); + continue; + }, + }; + + web3_instances.push(Web3Instance { + web3, + is_parity: version.contains("Parity") || version.contains("parity"), + }); + } + + if web3_instances.is_empty() { + return Err( + EthActivationV2Error::UnreachableNodes("Failed to get client version for all nodes".to_string()).into(), + ); + } + + Ok(web3_instances) +} diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index f850a4780a..c21cba1071 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -8,7 +8,7 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC7 use crate::common::Future01CompatExt; use bitcrypto::{dhash160, sha256}; use coins::eth::gas_limit::ETH_MAX_TRADE_GAS; -use coins::eth::v2_activation::{eth_coin_from_conf_and_request_v2, EthActivationV2Request, EthNode}; +use coins::eth::v2_activation::{eth_coin_from_conf_and_request_v2_for_test, EthActivationV2Request, EthNode}; use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_request, EthCoin, EthCoinType, EthPrivKeyBuildPolicy, SignedEthTx, SwapV2Contracts, ERC20_ABI}; use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; @@ -456,7 +456,7 @@ fn global_nft_with_random_privkey( path_to_address: Default::default(), gap_limit: None, }; - let coin = block_on(eth_coin_from_conf_and_request_v2( + let coin = block_on(eth_coin_from_conf_and_request_v2_for_test( &MM_CTX1, nft_ticker.as_str(), &nft_dev_conf(), @@ -576,7 +576,7 @@ fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, co path_to_address: Default::default(), gap_limit: None, }; - let coin = block_on(eth_coin_from_conf_and_request_v2( + let coin = block_on(eth_coin_from_conf_and_request_v2_for_test( ctx, ticker, conf, @@ -1639,7 +1639,7 @@ fn eth_coin_v2_activation_with_random_privkey( path_to_address: Default::default(), gap_limit: None, }; - let coin = block_on(eth_coin_from_conf_and_request_v2( + let coin = block_on(eth_coin_from_conf_and_request_v2_for_test( &MM_CTX1, ticker, conf, From 653c063bce33af9b0af4e85e3943a088e192f8f0 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 25 Aug 2024 08:10:16 +0700 Subject: [PATCH 225/233] review: remove unused code, except SwapAddresses::init and eth_coin_v2_activation_with_random_privkey --- .../tests/docker_tests/docker_tests_common.rs | 113 +-------- .../tests/docker_tests/eth_docker_tests.rs | 221 +----------------- .../contract_bytes/nft_swap_contract_bytes | 1 - 3 files changed, 8 insertions(+), 327 deletions(-) delete mode 100644 mm2src/mm2_test_helpers/contract_bytes/nft_swap_contract_bytes diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index dd030e3c25..1f627ab21e 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -58,21 +58,13 @@ lazy_static! { // Due to the SLP protocol limitations only 19 outputs (18 + change) can be sent in one transaction, which is sufficient for now though. // Supply more privkeys when 18 will be not enough. pub static ref SLP_TOKEN_OWNERS: Mutex> = Mutex::new(Vec::with_capacity(18)); - pub static ref MM_CTX: MmArc = { - let ctx = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); - init_p2p_context(&ctx); - ctx - }; + pub static ref MM_CTX: MmArc = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); /// We need a second `MmCtx` instance when we use the same private keys for Maker and Taker across various tests. /// When enabling coins for both Maker and Taker, two distinct coin instances are created. /// This means that different instances of the same coin should have separate global nonce locks. /// Utilizing different `MmCtx` instances allows us to assign Maker and Taker coins to separate `CoinsCtx`. /// This approach addresses the `replacement transaction` issue, which occurs when different transactions share the same nonce. - pub static ref MM_CTX1: MmArc = { - let ctx = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); - init_p2p_context(&ctx); - ctx - }; + pub static ref MM_CTX1: MmArc = MmCtxBuilder::new().with_conf(json!({"use_trading_proto_v2": true})).into_mm_arc(); pub static ref GETH_WEB3: Web3 = Web3::new(Http::new(GETH_RPC_URL).unwrap()); pub static ref SEPOLIA_WEB3: Web3 = Web3::new(Http::new(SEPOLIA_RPC_URL).unwrap()); // Mutex used to prevent nonce re-usage during funding addresses used in tests @@ -88,7 +80,6 @@ pub static mut QTUM_CONF_PATH: Option = None; pub static mut GETH_ACCOUNT: H160Eth = H160Eth::zero(); /// ERC20 token address on Geth dev node pub static mut GETH_ERC20_CONTRACT: H160Eth = H160Eth::zero(); -#[allow(dead_code)] pub static mut SEPOLIA_ERC20_CONTRACT: H160Eth = H160Eth::zero(); /// Swap contract address on Geth dev node pub static mut GETH_SWAP_CONTRACT: H160Eth = H160Eth::zero(); @@ -96,9 +87,7 @@ pub static mut GETH_SWAP_CONTRACT: H160Eth = H160Eth::zero(); pub static mut GETH_MAKER_SWAP_V2: H160Eth = H160Eth::zero(); /// Taker Swap V2 contract address on Geth dev node pub static mut GETH_TAKER_SWAP_V2: H160Eth = H160Eth::zero(); -#[allow(dead_code)] pub static mut SEPOLIA_TAKER_SWAP_V2: H160Eth = H160Eth::zero(); -#[allow(dead_code)] pub static mut SEPOLIA_MAKER_SWAP_V2: H160Eth = H160Eth::zero(); /// Swap contract (with watchers support) address on Geth dev node pub static mut GETH_WATCHERS_SWAP_CONTRACT: H160Eth = H160Eth::zero(); @@ -106,16 +95,10 @@ pub static mut GETH_WATCHERS_SWAP_CONTRACT: H160Eth = H160Eth::zero(); pub static mut GETH_ERC721_CONTRACT: H160Eth = H160Eth::zero(); /// ERC1155 token address on Geth dev node pub static mut GETH_ERC1155_CONTRACT: H160Eth = H160Eth::zero(); -/// Nft Swap contract address on Geth dev node -pub static mut GETH_NFT_SWAP_CONTRACT: H160Eth = H160Eth::zero(); /// NFT Maker Swap V2 contract address on Geth dev node pub static mut GETH_NFT_MAKER_SWAP_V2: H160Eth = H160Eth::zero(); /// NFT Maker Swap V2 contract address on Sepolia testnet pub static mut SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2: H160Eth = H160Eth::zero(); -/// ERC721 token address on Sepolia testnet -pub static mut SEPOLIA_ERC721_CONTRACT: H160Eth = H160Eth::zero(); -/// ERC1155 token address on Sepolia testnet -pub static mut SEPOLIA_ERC1155_CONTRACT: H160Eth = H160Eth::zero(); pub static GETH_RPC_URL: &str = "http://127.0.0.1:8545"; pub static SEPOLIA_RPC_URL: &str = "https://ethereum-sepolia-rpc.publicnode.com"; @@ -148,8 +131,6 @@ pub const ERC721_TEST_TOKEN_BYTES: &str = include_str!("../../../mm2_test_helpers/contract_bytes/erc721_test_token_bytes"); pub const ERC1155_TEST_TOKEN_BYTES: &str = include_str!("../../../mm2_test_helpers/contract_bytes/erc1155_test_token_bytes"); -pub const NFT_SWAP_CONTRACT_BYTES: &str = - include_str!("../../../mm2_test_helpers/contract_bytes/nft_swap_contract_bytes"); /// https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapMakerNftV2.sol pub const NFT_MAKER_SWAP_V2_BYTES: &str = include_str!("../../../mm2_test_helpers/contract_bytes/nft_maker_swap_v2_bytes"); @@ -1458,50 +1439,6 @@ pub fn init_geth_node() { thread::sleep(Duration::from_millis(100)); } - let dex_fee_address = Token::Address(geth_account()); - let params = ethabi::encode(&[dex_fee_address]); - let nft_swap_data = format!("{}{}", NFT_SWAP_CONTRACT_BYTES, hex::encode(params)); - - let tx_request_deploy_nft_swap_contract = TransactionRequest { - from: GETH_ACCOUNT, - to: None, - gas: None, - gas_price: None, - value: None, - data: Some(hex::decode(nft_swap_data).unwrap().into()), - nonce: None, - condition: None, - transaction_type: None, - access_list: None, - max_fee_per_gas: None, - max_priority_fee_per_gas: None, - }; - let deploy_nft_swap_tx_hash = - block_on(GETH_WEB3.eth().send_transaction(tx_request_deploy_nft_swap_contract)).unwrap(); - log!("Sent deploy nft swap contract transaction {:?}", deploy_swap_tx_hash); - - loop { - let deploy_nft_swap_tx_receipt = - match block_on(GETH_WEB3.eth().transaction_receipt(deploy_nft_swap_tx_hash)) { - Ok(receipt) => receipt, - Err(_) => { - thread::sleep(Duration::from_millis(100)); - continue; - }, - }; - - if let Some(receipt) = deploy_nft_swap_tx_receipt { - GETH_NFT_SWAP_CONTRACT = receipt.contract_address.unwrap(); - log!( - "GETH_NFT_SWAP_CONTRACT {:?}, receipt.status {:?}", - GETH_NFT_SWAP_CONTRACT, - receipt.status - ); - break; - } - thread::sleep(Duration::from_millis(100)); - } - let tx_request_deploy_nft_maker_swap_v2_contract = TransactionRequest { from: GETH_ACCOUNT, to: None, @@ -1549,50 +1486,6 @@ pub fn init_geth_node() { thread::sleep(Duration::from_millis(100)); } - let dex_fee_address = Token::Address(geth_account()); - let params = ethabi::encode(&[dex_fee_address]); - let nft_swap_data = format!("{}{}", NFT_SWAP_CONTRACT_BYTES, hex::encode(params)); - - let tx_request_deploy_nft_swap_contract = TransactionRequest { - from: GETH_ACCOUNT, - to: None, - gas: None, - gas_price: None, - value: None, - data: Some(hex::decode(nft_swap_data).unwrap().into()), - nonce: None, - condition: None, - transaction_type: None, - access_list: None, - max_fee_per_gas: None, - max_priority_fee_per_gas: None, - }; - let deploy_nft_swap_tx_hash = - block_on(GETH_WEB3.eth().send_transaction(tx_request_deploy_nft_swap_contract)).unwrap(); - log!("Sent deploy nft swap contract transaction {:?}", deploy_swap_tx_hash); - - loop { - let deploy_nft_swap_tx_receipt = - match block_on(GETH_WEB3.eth().transaction_receipt(deploy_nft_swap_tx_hash)) { - Ok(receipt) => receipt, - Err(_) => { - thread::sleep(Duration::from_millis(100)); - continue; - }, - }; - - if let Some(receipt) = deploy_nft_swap_tx_receipt { - GETH_NFT_SWAP_CONTRACT = receipt.contract_address.unwrap(); - log!( - "GETH_NFT_SWAP_CONTRACT {:?}, receipt.status {:?}", - GETH_NFT_SWAP_CONTRACT, - receipt.status - ); - break; - } - thread::sleep(Duration::from_millis(100)); - } - let name = Token::String("MyNFT".into()); let symbol = Token::String("MNFT".into()); let params = ethabi::encode(&[name, symbol]); @@ -1672,8 +1565,6 @@ pub fn init_geth_node() { } SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2 = EthAddress::from_str("0x9eb88cd58605d8fb9b14652d6152727f7e95fb4d").unwrap(); - SEPOLIA_ERC721_CONTRACT = EthAddress::from_str("0xbac1c9f2087f39caaa4e93412c6412809186870e").unwrap(); - SEPOLIA_ERC1155_CONTRACT = EthAddress::from_str("0xfb53b8764be6033d89ceacafa36631b09d60a1d2").unwrap(); SEPOLIA_ERC20_CONTRACT = EthAddress::from_str("0xF7b5F8E8555EF7A743f24D3E974E23A3C6cB6638").unwrap(); SEPOLIA_TAKER_SWAP_V2 = EthAddress::from_str("0x7Cc9F2c1c3B797D09B9d1CCd7FDcD2539a4b3874").unwrap(); // TODO update this diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index c21cba1071..a40c5b2132 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1,9 +1,8 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC721_TEST_ABI, GETH_ACCOUNT, GETH_ERC1155_CONTRACT, GETH_ERC20_CONTRACT, GETH_ERC721_CONTRACT, GETH_MAKER_SWAP_V2, - GETH_NFT_MAKER_SWAP_V2, GETH_NFT_SWAP_CONTRACT, GETH_NONCE_LOCK, GETH_RPC_URL, - GETH_SWAP_CONTRACT, GETH_TAKER_SWAP_V2, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, - MM_CTX, MM_CTX1, SEPOLIA_ERC1155_CONTRACT, SEPOLIA_ERC20_CONTRACT, - SEPOLIA_ERC721_CONTRACT, SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2, SEPOLIA_MAKER_SWAP_V2, + GETH_NFT_MAKER_SWAP_V2, GETH_NONCE_LOCK, GETH_RPC_URL, GETH_SWAP_CONTRACT, + GETH_TAKER_SWAP_V2, GETH_WATCHERS_SWAP_CONTRACT, GETH_WEB3, MM_CTX, MM_CTX1, + SEPOLIA_ERC20_CONTRACT, SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2, SEPOLIA_MAKER_SWAP_V2, SEPOLIA_NONCE_LOCK, SEPOLIA_RPC_URL, SEPOLIA_TAKER_SWAP_V2, SEPOLIA_WEB3}; use crate::common::Future01CompatExt; use bitcrypto::{dhash160, sha256}; @@ -21,14 +20,11 @@ use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, C SpendPaymentArgs, SwapOps, SwapTxFeePolicy, SwapTxTypeWithSecretHash, TakerCoinSwapOpsV2, ToBytes, Transaction, TxPreimageWithSig, ValidateNftMakerPaymentArgs, ValidateTakerFundingArgs}; use common::{block_on, now_sec}; -use crypto::{CryptoCtx, Secp256k1Secret}; +use crypto::Secp256k1Secret; use ethcore_transaction::Action; use ethereum_types::U256; -use futures::channel::mpsc; use futures01::Future; use mm2_core::mm_ctx::MmArc; -use mm2_libp2p::behaviours::atomicdex::generate_ed25519_keypair; -use mm2_net::p2p::P2PContext; use mm2_number::{BigDecimal, BigUint}; use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, eth_sepolia_conf, nft_dev_conf, nft_sepolia_conf, sepolia_erc20_dev_conf}; @@ -40,9 +36,7 @@ use web3::contract::{Contract, Options}; use web3::ethabi::Token; use web3::types::{Address, BlockNumber, TransactionRequest, H256}; -#[allow(dead_code)] const SEPOLIA_MAKER_PRIV: &str = "6e2f3a6223b928a05a3a3622b0c3f3573d03663b704a61a6eb73326de0487928"; -#[allow(dead_code)] const SEPOLIA_TAKER_PRIV: &str = "e0be82dca60ff7e4c6d6db339ac9e1ae249af081dba2110bddd281e711608f16"; const NFT_ETH: &str = "NFT_ETH"; const ETH: &str = "ETH"; @@ -52,84 +46,49 @@ const ERC20: &str = "ERC20DEV"; /// /// GETH_ACCOUNT is set once during initialization before tests start pub fn geth_account() -> Address { unsafe { GETH_ACCOUNT } } - /// # Safety /// /// GETH_SWAP_CONTRACT is set once during initialization before tests start pub fn swap_contract() -> Address { unsafe { GETH_SWAP_CONTRACT } } - /// # Safety /// /// GETH_MAKER_SWAP_V2 is set once during initialization before tests start pub fn maker_swap_v2() -> Address { unsafe { GETH_MAKER_SWAP_V2 } } - /// # Safety /// /// GETH_TAKER_SWAP_V2 is set once during initialization before tests start pub fn taker_swap_v2() -> Address { unsafe { GETH_TAKER_SWAP_V2 } } -#[allow(dead_code)] pub fn sepolia_taker_swap_v2() -> Address { unsafe { SEPOLIA_TAKER_SWAP_V2 } } -#[allow(dead_code)] pub fn sepolia_maker_swap_v2() -> Address { unsafe { SEPOLIA_MAKER_SWAP_V2 } } - -#[allow(dead_code)] -/// # Safety -/// -/// GETH_NFT_SWAP_CONTRACT is set once during initialization before tests start -pub fn nft_swap_contract() -> Address { unsafe { GETH_NFT_SWAP_CONTRACT } } - /// # Safety /// /// GETH_NFT_MAKER_SWAP_V2 is set once during initialization before tests start pub fn geth_nft_maker_swap_v2() -> Address { unsafe { GETH_NFT_MAKER_SWAP_V2 } } - /// # Safety /// /// GETH_WATCHERS_SWAP_CONTRACT is set once during initialization before tests start pub fn watchers_swap_contract() -> Address { unsafe { GETH_WATCHERS_SWAP_CONTRACT } } - /// # Safety /// /// GETH_ERC20_CONTRACT is set once during initialization before tests start pub fn erc20_contract() -> Address { unsafe { GETH_ERC20_CONTRACT } } -#[allow(dead_code)] pub fn sepolia_erc20_contract() -> Address { unsafe { SEPOLIA_ERC20_CONTRACT } } - /// Return ERC20 dev token contract address in checksum format pub fn erc20_contract_checksum() -> String { checksum_address(&format!("{:02x}", erc20_contract())) } -#[allow(dead_code)] pub fn sepolia_erc20_contract_checksum() -> String { checksum_address(&format!("{:02x}", sepolia_erc20_contract())) } - -#[allow(dead_code)] /// # Safety /// /// GETH_ERC721_CONTRACT is set once during initialization before tests start pub fn geth_erc721_contract() -> Address { unsafe { GETH_ERC721_CONTRACT } } - -#[allow(dead_code)] /// # Safety /// /// GETH_ERC1155_CONTRACT is set once during initialization before tests start pub fn geth_erc1155_contract() -> Address { unsafe { GETH_ERC1155_CONTRACT } } - -#[allow(dead_code)] /// # Safety /// /// SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2 address is set once during initialization before tests start pub fn sepolia_etomic_maker_nft() -> Address { unsafe { SEPOLIA_ETOMIC_MAKER_NFT_SWAP_V2 } } -#[allow(dead_code)] -/// # Safety -/// -/// SEPOLIA_ERC721_CONTRACT address is set once during initialization before tests start -pub fn sepolia_erc721() -> Address { unsafe { SEPOLIA_ERC721_CONTRACT } } - -#[allow(dead_code)] -/// # Safety -/// -/// SEPOLIA_ERC1155_CONTRACT address is set once during initialization before tests start -pub fn sepolia_erc1155() -> Address { unsafe { SEPOLIA_ERC1155_CONTRACT } } - fn wait_for_confirmation(tx_hash: H256) { thread::sleep(Duration::from_millis(2000)); loop { @@ -179,32 +138,6 @@ fn fill_erc20(to_addr: Address, amount: U256) { wait_for_confirmation(tx_hash); } -#[allow(dead_code)] -fn check_eth_balance(address: Address) -> U256 { - let _guard = GETH_NONCE_LOCK.lock().unwrap(); - block_on(GETH_WEB3.eth().balance(address, None)).unwrap() -} - -#[allow(dead_code)] -fn sepolia_check_eth_balance(address: Address) -> U256 { - let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); - block_on(SEPOLIA_WEB3.eth().balance(address, None)).unwrap() -} - -#[allow(dead_code)] -fn check_erc20_balance(address: Address) -> U256 { - let _guard = GETH_NONCE_LOCK.lock().unwrap(); - let erc20_contract = Contract::from_json(GETH_WEB3.eth(), erc20_contract(), ERC20_ABI.as_bytes()).unwrap(); - block_on(erc20_contract.query("balanceOf", (address,), None, Options::default(), None)).unwrap() -} - -#[allow(dead_code)] -fn sepolia_check_erc20_balance(address: Address) -> U256 { - let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); - let erc20_contract = Contract::from_json(SEPOLIA_WEB3.eth(), erc20_contract(), ERC20_ABI.as_bytes()).unwrap(); - block_on(erc20_contract.query("balanceOf", (address,), None, Options::default(), None)).unwrap() -} - fn mint_erc721(to_addr: Address, token_id: U256) { let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc721_contract = @@ -402,30 +335,6 @@ pub enum TestNftType { Erc721 { token_id: u32 }, } -pub(crate) fn init_p2p_context(ctx: &MmArc) { - let (cmd_tx, _) = mpsc::channel(512); - - let p2p_key = { - let crypto_ctx = match CryptoCtx::from_ctx(ctx) { - Ok(crypto_ctx) => crypto_ctx, - Err(_) => CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "passphrase").unwrap(), - }; - let key = sha256(crypto_ctx.mm2_internal_privkey_slice()); - key.take() - }; - - let p2p_context = P2PContext::new(cmd_tx, generate_ed25519_keypair(p2p_key)); - p2p_context.store_to_mm_arc(ctx); -} - -#[allow(dead_code)] -fn ensure_p2p_context(ctx: &MmArc) { - let p2p_ctx_lock = ctx.p2p_ctx.lock().unwrap(); - if p2p_ctx_lock.is_none() { - init_p2p_context(ctx); - } -} - /// Generates a global NFT coin instance with a random private key and an initial 100 ETH balance. /// Optionally mints a specified NFT (either ERC721 or ERC1155) to the global NFT address, /// with details recorded in the `nfts_infos` field based on the provided `nft_type`. @@ -492,57 +401,6 @@ fn global_nft_with_random_privkey( global_nft } -#[allow(dead_code)] -/// Can be used to generate global NFT from Sepolia Maker/Taker priv keys. -fn global_nft_from_privkey( - ctx: &MmArc, - swap_contract_address: Address, - secret: &'static str, - nft_type: Option, -) -> EthCoin { - let nft_conf = nft_sepolia_conf(); - let req = json!({ - "method": "enable", - "coin": "NFT_ETH", - "urls": [SEPOLIA_RPC_URL], - "swap_contract_address": swap_contract_address, - }); - - let priv_key = Secp256k1Secret::from(secret); - let global_nft = block_on(eth_coin_from_conf_and_request( - ctx, - NFT_ETH, - &nft_conf, - &req, - CoinProtocol::NFT { - platform: "ETH".to_string(), - }, - PrivKeyBuildPolicy::IguanaPrivKey(priv_key), - )) - .unwrap(); - - let coins_ctx = CoinsContext::from_ctx(ctx).unwrap(); - let mut coins = block_on(coins_ctx.lock_coins()); - coins.insert( - global_nft.ticker().into(), - MmCoinStruct::new(MmCoinEnum::EthCoin(global_nft.clone())), - ); - - if let Some(nft_type) = nft_type { - match nft_type { - TestNftType::Erc1155 { token_id, amount } => { - block_on(fill_erc1155_info(&global_nft, sepolia_erc1155(), token_id, amount)); - }, - TestNftType::Erc721 { token_id } => { - block_on(fill_erc721_info(&global_nft, sepolia_erc721(), token_id)); - }, - } - } - - global_nft -} - -#[allow(dead_code)] /// Can be used to generate coin from Sepolia Maker/Taker priv keys. fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, conf: &Json, erc20: bool) -> EthCoin { let swap_addr = SwapAddresses { @@ -603,7 +461,6 @@ fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, co coin } -#[allow(dead_code)] fn get_or_create_sepolia_coin(ctx: &MmArc, priv_key: &'static str, ticker: &str, conf: &Json, erc20: bool) -> EthCoin { match block_on(lp_coinfind(ctx, ticker)).unwrap() { None => sepolia_coin_from_privkey(ctx, priv_key, ticker, conf, erc20), @@ -614,62 +471,6 @@ fn get_or_create_sepolia_coin(ctx: &MmArc, priv_key: &'static str, ticker: &str, } } -#[allow(dead_code)] -fn send_safe_transfer_from( - global_nft: &EthCoin, - token_address: Address, - from_address: Address, - to_address: Address, - nft_type: TestNftType, -) -> web3::Result { - let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); - - let contract = match nft_type { - TestNftType::Erc1155 { .. } => { - Contract::from_json(SEPOLIA_WEB3.eth(), token_address, ERC1155_TEST_ABI.as_bytes()).unwrap() - }, - TestNftType::Erc721 { .. } => { - Contract::from_json(SEPOLIA_WEB3.eth(), token_address, ERC721_TEST_ABI.as_bytes()).unwrap() - }, - }; - let tokens = match nft_type { - TestNftType::Erc1155 { token_id, amount } => vec![ - Token::Address(from_address), - Token::Address(to_address), - Token::Uint(U256::from(token_id)), - Token::Uint(U256::from(amount)), - Token::Bytes(vec![]), - ], - TestNftType::Erc721 { token_id } => vec![ - Token::Address(from_address), - Token::Address(to_address), - Token::Uint(U256::from(token_id)), - ], - }; - - let data = contract - .abi() - .function("safeTransferFrom") - .unwrap() - .encode_input(&tokens) - .unwrap(); - - let result = block_on( - global_nft - .sign_and_send_transaction( - 0.into(), - Action::Call(token_address), - data, - U256::from(ETH_MAX_TRADE_GAS), - ) - .compat(), - ) - .unwrap(); - - log!("Transaction sent: {:?}", result); - Ok(result) -} - /// Fills the private key's public address with ETH and ERC20 tokens pub fn fill_eth_erc20_with_private_key(priv_key: Secp256k1Secret) { let eth_conf = eth_dev_conf(); @@ -1060,7 +861,6 @@ fn send_and_spend_erc20_maker_payment_priority_fee() { send_and_spend_erc20_maker_payment_impl(SwapTxFeePolicy::Medium); } -#[allow(dead_code)] /// Wait for all pending transactions for the given address to be confirmed fn wait_pending_transactions(wallet_address: Address) { let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); @@ -1087,17 +887,6 @@ fn wait_pending_transactions(wallet_address: Address) { } } -#[allow(dead_code)] -fn get_or_create_nft(ctx: &MmArc, priv_key: &'static str, nft_type: Option) -> EthCoin { - match block_on(lp_coinfind(ctx, NFT_ETH)).unwrap() { - None => global_nft_from_privkey(ctx, sepolia_etomic_maker_nft(), priv_key, nft_type), - Some(mm_coin) => match mm_coin { - MmCoinEnum::EthCoin(nft) => nft, - _ => panic!("Unexpected coin type found. Expected MmCoinEnum::EthCoin"), - }, - } -} - #[test] fn send_and_spend_erc721_maker_payment() { let token_id = 1u32; @@ -1599,6 +1388,7 @@ struct SwapAddresses { } #[allow(dead_code)] +/// Needed for Geth taker or maker swap v2 tests impl SwapAddresses { fn init() -> Self { Self { @@ -1614,6 +1404,7 @@ impl SwapAddresses { } #[allow(dead_code)] +/// Needed for eth or erc20 v2 activation in Geth tests fn eth_coin_v2_activation_with_random_privkey( ticker: &str, conf: &Json, diff --git a/mm2src/mm2_test_helpers/contract_bytes/nft_swap_contract_bytes b/mm2src/mm2_test_helpers/contract_bytes/nft_swap_contract_bytes deleted file mode 100644 index 44c1930271..0000000000 --- a/mm2src/mm2_test_helpers/contract_bytes/nft_swap_contract_bytes +++ /dev/null @@ -1 +0,0 @@ -60a060405234801562000010575f80fd5b50604051620055a2380380620055a2833981810160405281019062000036919062000147565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200009e90620001fb565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506200021b565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200011182620000e6565b9050919050565b620001238162000105565b81146200012e575f80fd5b50565b5f81519050620001418162000118565b92915050565b5f602082840312156200015f576200015e620000e2565b5b5f6200016e8482850162000131565b91505092915050565b5f82825260208201905092915050565b7f66656541646472657373206d757374206e6f74206265207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f620001e360238362000177565b9150620001f08262000187565b604082019050919050565b5f6020820190508181035f8301526200021481620001d5565b9050919050565b608051615360620002425f395f8181612aef01528181612b8a0152612f4801526153605ff3fe608060405260043610610113575f3560e01c80639b4603f21161009f578063cc90c19911610063578063cc90c1991461038e578063d6a71eb4146103b6578063e06cf966146103de578063efccb9eb14610408578063f23a6e611461044657610113565b80639b4603f2146102be578063b27e46fb146102da578063bc197c8114610302578063c8d9009b1461033e578063c92cd12d1461036657610113565b8063150b7a02116100e6578063150b7a02146101cb5780633e6af5f21461020757806346b95ac71461022f57806365e266171461026e5780636e6bf6d21461029657610113565b806301ffc9a71461011757806305ec158d146101535780630f235fce1461017b578063146e5b24146101a3575b5f80fd5b348015610122575f80fd5b5061013d6004803603810190610138919061386f565b610482565b60405161014a91906138b4565b60405180910390f35b34801561015e575f80fd5b506101796004803603810190610174919061398d565b610563565b005b348015610186575f80fd5b506101a1600480360381019061019c9190613a2a565b610823565b005b3480156101ae575f80fd5b506101c960048036038101906101c49190613ab3565b610add565b005b3480156101d6575f80fd5b506101f160048036038101906101ec9190613bb1565b610cc3565b6040516101fe9190613c44565b60405180910390f35b348015610212575f80fd5b5061022d60048036038101906102289190613ab3565b611112565b005b34801561023a575f80fd5b5061025560048036038101906102509190613c5d565b611423565b6040516102659493929190613d53565b60405180910390f35b348015610279575f80fd5b50610294600480360381019061028f9190613ab3565b611485565b005b3480156102a1575f80fd5b506102bc60048036038101906102b79190613a2a565b6118e9565b005b6102d860048036038101906102d39190613dc0565b611ba4565b005b3480156102e5575f80fd5b5061030060048036038101906102fb919061398d565b611eda565b005b34801561030d575f80fd5b5061032860048036038101906103239190613eb2565b612199565b6040516103359190613c44565b60405180910390f35b348015610349575f80fd5b50610364600480360381019061035f9190613a2a565b6121d5565b005b348015610371575f80fd5b5061038c6004803603810190610387919061398d565b6124fe565b005b348015610399575f80fd5b506103b460048036038101906103af9190613ab3565b61282c565b005b3480156103c1575f80fd5b506103dc60048036038101906103d79190613f89565b612bdc565b005b3480156103e9575f80fd5b506103f2612f46565b6040516103ff919061405c565b60405180910390f35b348015610413575f80fd5b5061042e60048036038101906104299190613c5d565b612f6a565b60405161043d939291906140bb565b60405180910390f35b348015610451575f80fd5b5061046c600480360381019061046791906140f0565b612fb6565b6040516104799190613c44565b60405180910390f35b5f7f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061054c57507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061055c575061055b8261344a565b5b9050919050565b6001600381111561057757610576613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff1660038111156105a9576105a8613ce0565b5b146105e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e090614206565b60405180910390fd5b5f600387336002896040516020016106019190614244565b60405160208183030381529060405260405161061d91906142ca565b602060405180830381855afa158015610638573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065b91906142f4565b888888886040516020016106759796959493929190614384565b60405160208183030381529060405260405161069191906142ca565b602060405180830381855afa1580156106ac573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610736576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072d9061444e565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561076c5761076b613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd73886040516107a0919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016107eb94939291906144d6565b5f604051808303815f87803b158015610802575f80fd5b505af1158015610814573d5f803e3d5ffd5b50505050505050505050505050565b6001600381111561083757610836613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561086957610868613ce0565b5b146108a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a090614206565b60405180910390fd5b5f60038633878787876040516020016108c79695949392919061452c565b6040516020818303038152906040526040516108e391906142ca565b602060405180830381855afa1580156108fe573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097f9061444e565b60405180910390fd5b5f808881526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156109f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ea9061460b565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115610a2957610a28613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907287604051610a5d919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401610aa693929190614629565b5f604051808303815f87803b158015610abd575f80fd5b505af1158015610acf573d5f803e3d5ffd5b505050505050505050505050565b60016004811115610af157610af0613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115610b2457610b23613ce0565b5b14610b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5b90614206565b60405180910390fd5b5f600387878733888888604051602001610b84979695949392919061465e565b604051602081830303815290604052604051610ba091906142ca565b602060405180830381855afa158015610bbb573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614610c46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3d9061444e565b60405180910390fd5b600260015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115610c7d57610c7c613ce0565b5b02179055507f9c45e43e2ef051f70491ffd5221bf02ab37e1324128714ef9610df5f24fc9fb588604051610cb1919061447b565b60405180910390a15050505050505050565b5f808383810190610cd49190614807565b90505f6003811115610ce957610ce8613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff166003811115610d1e57610d1d613ce0565b5b14610d5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d55906148a2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1603610dd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc79061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603610e42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3990614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610eb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eab90614a00565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614610f22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1990614a68565b60405180910390fd5b610f2f81602001516134b3565b15610f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6690614ad0565b60405180910390fd5b5f60038260200151888460600151856080015186604001518b604051602001610f9d9695949392919061452c565b604051602081830303815290604052604051610fb991906142ca565b602060405180830381855afa158015610fd4573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561102457611023613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156110bb576110ba613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f01516040516110f5919061447b565b60405180910390a163150b7a0260e01b9250505095945050505050565b6001600481111561112657611125613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561115957611158613ce0565b5b14611199576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119090614206565b60405180910390fd5b5f6003878787336002896040516020016111b39190614244565b6040516020818303038152906040526040516111cf91906142ca565b602060405180830381855afa1580156111ea573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061120d91906142f4565b8888604051602001611225979695949392919061465e565b60405160208183030381529060405260405161124191906142ca565b602060405180830381855afa15801561125c573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff1916146112e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112de9061444e565b60405180910390fd5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff0219169083600481111561131e5761131d613ce0565b5b02179055507f45169a52eef651b20a81474b50b8a5d83225225fcd097ef3cf7952d9ab304f278885604051611354929190614aee565b60405180910390a15f86886113699190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113e7573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156113e1573d5f803e3d5ffd5b50611418565b5f83905061141633838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b6001602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900463ffffffff1690805f01601c9054906101000a900460ff16905084565b6001600481111561149957611498613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff1660048111156114cc576114cb613ce0565b5b148061151c5750600260048111156114e7576114e6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561151a57611519613ce0565b5b145b61155b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155290614be5565b60405180910390fd5b5f60038787873388888860405160200161157b979695949392919061465e565b60405160208183030381529060405260405161159791906142ca565b602060405180830381855afa1580156115b2573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461163d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116349061444e565b60405180910390fd5b6002600481111561165157611650613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561168457611683613ce0565b5b036116f65760015f8981526020019081526020015f205f0160189054906101000a900463ffffffff1663ffffffff164210156116f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ec9061460b565b60405180910390fd5b5b6001600481111561170a57611709613ce0565b5b60015f8a81526020019081526020015f205f01601c9054906101000a900460ff16600481111561173d5761173c613ce0565b5b036117af5760015f8981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156117ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a590614c73565b60405180910390fd5b5b600460015f8a81526020019081526020015f205f01601c6101000a81548160ff021916908360048111156117e6576117e5613ce0565b5b02179055507fbdd7a4be6d82798a500b59077706b12d3f45acf5504828919f92501307b2b9538860405161181a919061447b565b60405180910390a15f868861182f9190614b42565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118ad573373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156118a7573d5f803e3d5ffd5b506118de565b5f8390506118dc33838373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b505050505050505050565b600160038111156118fd576118fc613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561192f5761192e613ce0565b5b1461196f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196690614206565b60405180910390fd5b5f600386336002886040516020016119879190614244565b6040516020818303038152906040526040516119a391906142ca565b602060405180830381855afa1580156119be573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906119e191906142f4565b8787876040516020016119f99695949392919061452c565b604051602081830303815290604052604051611a1591906142ca565b602060405180830381855afa158015611a30573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614611aba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab19061444e565b60405180910390fd5b60035f808981526020019081526020015f205f0160186101000a81548160ff02191690836003811115611af057611aef613ce0565b5b02179055507fac509cdcc7ddb189f81fff6f4824f5c95076e64c3bdce542c50feaa6779afd7387604051611b24919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b8152600401611b6d93929190614629565b5f604051808303815f87803b158015611b84575f80fd5b505af1158015611b96573d5f803e3d5ffd5b505050505050505050505050565b5f6004811115611bb757611bb6613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff166004811115611bea57611be9613ce0565b5b14611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2190614d01565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611c98576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8f90614d8f565b60405180910390fd5b5f3411611cda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd190614e1d565b60405180910390fd5b853411611d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1390614eab565b60405180910390fd5b5f60038734611d2b9190614ec9565b88883389895f604051602001611d47979695949392919061465e565b604051602081830303815290604052604051611d6391906142ca565b602060405180830381855afa158015611d7e573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115611dd657611dd5613ce0565b5b81525060015f8a81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115611e9157611e90613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd93588604051611ec8919061447b565b60405180910390a15050505050505050565b60016003811115611eee57611eed613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff166003811115611f2057611f1f613ce0565b5b14611f60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5790614206565b60405180910390fd5b5f600387338888888888604051602001611f809796959493929190614384565b604051602081830303815290604052604051611f9c91906142ca565b602060405180830381855afa158015611fb7573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612041576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120389061444e565b60405180910390fd5b5f808981526020019081526020015f205f0160149054906101000a900463ffffffff1663ffffffff164210156120ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a39061460b565b60405180910390fd5b60035f808a81526020019081526020015f205f0160186101000a81548160ff021916908360038111156120e2576120e1613ce0565b5b02179055507f5dedc4f52b757d9112d09ca0b2f022927104d54e3f54da091587e8ad1921907288604051612116919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b815260040161216194939291906144d6565b5f604051808303815f87803b158015612178575f80fd5b505af115801561218a573d5f803e3d5ffd5b50505050505050505050505050565b5f6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121cc90614f46565b60405180910390fd5b600160038111156121e9576121e8613ce0565b5b5f808881526020019081526020015f205f0160189054906101000a900460ff16600381111561221b5761221a613ce0565b5b1461225b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161225290614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c090614fae565b60405180910390fd5b5f60033387876002886040516020016122e29190614244565b6040516020818303038152906040526040516122fe91906142ca565b602060405180830381855afa158015612319573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061233c91906142f4565b87876040516020016123539695949392919061452c565b60405160208183030381529060405260405161236f91906142ca565b602060405180830381855afa15801561238a573d5f803e3d5ffd5b5050506040515160601b90505f808881526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612414576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240b9061444e565b60405180910390fd5b60025f808981526020019081526020015f205f0160186101000a81548160ff0219169083600381111561244a57612449613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf08760405161247e919061447b565b60405180910390a15f8390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3033866040518463ffffffff1660e01b81526004016124c793929190614629565b5f604051808303815f87803b1580156124de575f80fd5b505af11580156124f0573d5f803e3d5ffd5b505050505050505050505050565b6001600381111561251257612511613ce0565b5b5f808981526020019081526020015f205f0160189054906101000a900460ff16600381111561254457612543613ce0565b5b14612584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257b90614206565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146125f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125e990614fae565b60405180910390fd5b5f600333888860028960405160200161260b9190614244565b60405160208183030381529060405260405161262791906142ca565b602060405180830381855afa158015612642573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061266591906142f4565b88888860405160200161267e9796959493929190614384565b60405160208183030381529060405260405161269a91906142ca565b602060405180830381855afa1580156126b5573d5f803e3d5ffd5b5050506040515160601b90505f808981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff19161461273f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127369061444e565b60405180910390fd5b60025f808a81526020019081526020015f205f0160186101000a81548160ff0219169083600381111561277557612774613ce0565b5b02179055507fad62ed075fe8969df63026f45152d6e996a0697a736a8de92ee85ae9c9958cf0886040516127a9919061447b565b60405180910390a15f8490508073ffffffffffffffffffffffffffffffffffffffff1663f242432a303387876040518563ffffffff1660e01b81526004016127f494939291906144d6565b5f604051808303815f87803b15801561280b575f80fd5b505af115801561281d573d5f803e3d5ffd5b50505050505050505050505050565b600260048111156128405761283f613ce0565b5b60015f8981526020019081526020015f205f01601c9054906101000a900460ff16600481111561287357612872613ce0565b5b146128b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128aa9061503c565b60405180910390fd5b5f600387873388886002896040516020016128ce9190614244565b6040516020818303038152906040526040516128ea91906142ca565b602060405180830381855afa158015612905573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061292891906142f4565b8860405160200161293f979695949392919061465e565b60405160208183030381529060405260405161295b91906142ca565b602060405180830381855afa158015612976573d5f803e3d5ffd5b5050506040515160601b905060015f8981526020019081526020015f205f015f9054906101000a900460601b6bffffffffffffffffffffffff1916816bffffffffffffffffffffffff191614612a01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129f89061444e565b60405180910390fd5b600360015f8a81526020019081526020015f205f01601c6101000a81548160ff02191690836004811115612a3857612a37613ce0565b5b02179055507f0d0da0df275f85bed3a5fe7ae79f3559341a3f9ccd8e010133438135bda00a878884604051612a6e929190614aee565b60405180910390a15f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612b56573373ffffffffffffffffffffffffffffffffffffffff166108fc8890811502906040515f60405180830381858888f19350505050158015612aec573d5f803e3d5ffd5b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108fc8790811502906040515f60405180830381858888f19350505050158015612b50573d5f803e3d5ffd5b50612bd2565b5f829050612b8533898373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b612bd07f0000000000000000000000000000000000000000000000000000000000000000888373ffffffffffffffffffffffffffffffffffffffff166134c49092919063ffffffff16565b505b5050505050505050565b5f6004811115612bef57612bee613ce0565b5b60015f8b81526020019081526020015f205f01601c9054906101000a900460ff166004811115612c2257612c21613ce0565b5b14612c62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c59906150ca565b60405180910390fd5b5f8811612ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c9b90615132565b60405180910390fd5b5f8711612ce6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cdd9061519a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612d54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d4b90614d8f565b60405180910390fd5b5f60038989883389898d604051602001612d74979695949392919061465e565b604051602081830303815290604052604051612d9091906142ca565b602060405180830381855afa158015612dab573d5f803e3d5ffd5b5050506040515160601b90506040518060800160405280826bffffffffffffffffffffffff191681526020018463ffffffff1681526020018363ffffffff16815260200160016004811115612e0357612e02613ce0565b5b81525060015f8c81526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548163ffffffff021916908363ffffffff1602179055506060820151815f01601c6101000a81548160ff02191690836004811115612ebe57612ebd613ce0565b5b02179055509050507ffc6cdccd1d98ded12074a9ebc7f6ab74fed1814ff57f4fb5202464d8938bd9358a604051612ef5919061447b565b60405180910390a15f879050612f3933308b8d612f129190614b42565b8473ffffffffffffffffffffffffffffffffffffffff16613543909392919063ffffffff16565b5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f602052805f5260405f205f91509050805f015f9054906101000a900460601b90805f0160149054906101000a900463ffffffff1690805f0160189054906101000a900460ff16905083565b5f808383810190612fc79190614807565b90505f6003811115612fdc57612fdb613ce0565b5b5f80835f015181526020019081526020015f205f0160189054906101000a900460ff16600381111561301157613010613ce0565b5b14613051576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161304890615228565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff16036130c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130ba9061490a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1603613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161312c90614972565b60405180910390fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146131a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161319e90614a00565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614613215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161320c90614a68565b60405180910390fd5b5f8511613257576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161324e90615290565b60405180910390fd5b61326481602001516134b3565b156132a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161329b90614ad0565b60405180910390fd5b5f60038260200151898460600151856080015186604001518c8c6040516020016132d49796959493929190614384565b6040516020818303038152906040526040516132f091906142ca565b602060405180830381855afa15801561330b573d5f803e3d5ffd5b5050506040515160601b90506040518060600160405280826bffffffffffffffffffffffff191681526020018360a0015163ffffffff1681526020016001600381111561335b5761335a613ce0565b5b8152505f80845f015181526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908360601c02179055506020820151815f0160146101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160186101000a81548160ff021916908360038111156133f2576133f1613ce0565b5b02179055509050507ff1dc11bbb6d7542c4267ecf1d370ff4c7092518633ecae9939e8488f4e53d2ad825f015160405161342c919061447b565b60405180910390a163f23a6e6160e01b925050509695505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f80823b90505f8111915050919050565b61353e838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85856040516024016134f79291906152ae565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b505050565b6135bf848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161357893929190614629565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506135c5565b50505050565b5f6135ef828473ffffffffffffffffffffffffffffffffffffffff1661365a90919063ffffffff16565b90505f81511415801561361357508080602001905181019061361191906152ff565b155b1561365557826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161364c919061405c565b60405180910390fd5b505050565b606061366783835f61366f565b905092915050565b6060814710156136b657306040517fcd7860590000000000000000000000000000000000000000000000000000000081526004016136ad919061405c565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516136de91906142ca565b5f6040518083038185875af1925050503d805f8114613718576040519150601f19603f3d011682016040523d82523d5f602084013e61371d565b606091505b509150915061372d868383613738565b925050509392505050565b60608261374d57613748826137c5565b6137bd565b5f825114801561377357505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156137b557836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016137ac919061405c565b60405180910390fd5b8190506137be565b5b9392505050565b5f815111156137d75780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61384e8161381a565b8114613858575f80fd5b50565b5f8135905061386981613845565b92915050565b5f6020828403121561388457613883613812565b5b5f6138918482850161385b565b91505092915050565b5f8115159050919050565b6138ae8161389a565b82525050565b5f6020820190506138c75f8301846138a5565b92915050565b5f819050919050565b6138df816138cd565b81146138e9575f80fd5b50565b5f813590506138fa816138d6565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61392982613900565b9050919050565b6139398161391f565b8114613943575f80fd5b50565b5f8135905061395481613930565b92915050565b5f819050919050565b61396c8161395a565b8114613976575f80fd5b50565b5f8135905061398781613963565b92915050565b5f805f805f805f60e0888a0312156139a8576139a7613812565b5b5f6139b58a828b016138ec565b97505060206139c68a828b01613946565b96505060406139d78a828b016138ec565b95505060606139e88a828b016138ec565b94505060806139f98a828b01613946565b93505060a0613a0a8a828b01613979565b92505060c0613a1b8a828b01613979565b91505092959891949750929550565b5f805f805f8060c08789031215613a4457613a43613812565b5b5f613a5189828a016138ec565b9650506020613a6289828a01613946565b9550506040613a7389828a016138ec565b9450506060613a8489828a016138ec565b9350506080613a9589828a01613946565b92505060a0613aa689828a01613979565b9150509295509295509295565b5f805f805f805f60e0888a031215613ace57613acd613812565b5b5f613adb8a828b016138ec565b9750506020613aec8a828b01613979565b9650506040613afd8a828b01613979565b9550506060613b0e8a828b01613946565b9450506080613b1f8a828b016138ec565b93505060a0613b308a828b016138ec565b92505060c0613b418a828b01613946565b91505092959891949750929550565b5f80fd5b5f80fd5b5f80fd5b5f8083601f840112613b7157613b70613b50565b5b8235905067ffffffffffffffff811115613b8e57613b8d613b54565b5b602083019150836001820283011115613baa57613ba9613b58565b5b9250929050565b5f805f805f60808688031215613bca57613bc9613812565b5b5f613bd788828901613946565b9550506020613be888828901613946565b9450506040613bf988828901613979565b935050606086013567ffffffffffffffff811115613c1a57613c19613816565b5b613c2688828901613b5c565b92509250509295509295909350565b613c3e8161381a565b82525050565b5f602082019050613c575f830184613c35565b92915050565b5f60208284031215613c7257613c71613812565b5b5f613c7f848285016138ec565b91505092915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b613cbc81613c88565b82525050565b5f63ffffffff82169050919050565b613cda81613cc2565b82525050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60058110613d1e57613d1d613ce0565b5b50565b5f819050613d2e82613d0d565b919050565b5f613d3d82613d21565b9050919050565b613d4d81613d33565b82525050565b5f608082019050613d665f830187613cb3565b613d736020830186613cd1565b613d806040830185613cd1565b613d8d6060830184613d44565b95945050505050565b613d9f81613cc2565b8114613da9575f80fd5b50565b5f81359050613dba81613d96565b92915050565b5f805f805f805f60e0888a031215613ddb57613dda613812565b5b5f613de88a828b016138ec565b9750506020613df98a828b01613979565b9650506040613e0a8a828b01613946565b9550506060613e1b8a828b016138ec565b9450506080613e2c8a828b016138ec565b93505060a0613e3d8a828b01613dac565b92505060c0613e4e8a828b01613dac565b91505092959891949750929550565b5f8083601f840112613e7257613e71613b50565b5b8235905067ffffffffffffffff811115613e8f57613e8e613b54565b5b602083019150836020820283011115613eab57613eaa613b58565b5b9250929050565b5f805f805f805f8060a0898b031215613ece57613ecd613812565b5b5f613edb8b828c01613946565b9850506020613eec8b828c01613946565b975050604089013567ffffffffffffffff811115613f0d57613f0c613816565b5b613f198b828c01613e5d565b9650965050606089013567ffffffffffffffff811115613f3c57613f3b613816565b5b613f488b828c01613e5d565b9450945050608089013567ffffffffffffffff811115613f6b57613f6a613816565b5b613f778b828c01613b5c565b92509250509295985092959890939650565b5f805f805f805f805f6101208a8c031215613fa757613fa6613812565b5b5f613fb48c828d016138ec565b9950506020613fc58c828d01613979565b9850506040613fd68c828d01613979565b9750506060613fe78c828d01613946565b9650506080613ff88c828d01613946565b95505060a06140098c828d016138ec565b94505060c061401a8c828d016138ec565b93505060e061402b8c828d01613dac565b92505061010061403d8c828d01613dac565b9150509295985092959850929598565b6140568161391f565b82525050565b5f60208201905061406f5f83018461404d565b92915050565b6004811061408657614085613ce0565b5b50565b5f81905061409682614075565b919050565b5f6140a582614089565b9050919050565b6140b58161409b565b82525050565b5f6060820190506140ce5f830186613cb3565b6140db6020830185613cd1565b6140e860408301846140ac565b949350505050565b5f805f805f8060a0878903121561410a57614109613812565b5b5f61411789828a01613946565b965050602061412889828a01613946565b955050604061413989828a01613979565b945050606061414a89828a01613979565b935050608087013567ffffffffffffffff81111561416b5761416a613816565b5b61417789828a01613b5c565b92509250509295509295509295565b5f82825260208201905092915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e7400000000000000000000000000000000000000000000602082015250565b5f6141f0602a83614186565b91506141fb82614196565b604082019050919050565b5f6020820190508181035f83015261421d816141e4565b9050919050565b5f819050919050565b61423e614239826138cd565b614224565b82525050565b5f61424f828461422d565b60208201915081905092915050565b5f81519050919050565b5f81905092915050565b5f5b8381101561428f578082015181840152602081019050614274565b5f8484015250505050565b5f6142a48261425e565b6142ae8185614268565b93506142be818560208601614272565b80840191505092915050565b5f6142d5828461429a565b915081905092915050565b5f815190506142ee816138d6565b92915050565b5f6020828403121561430957614308613812565b5b5f614316848285016142e0565b91505092915050565b5f8160601b9050919050565b5f6143358261431f565b9050919050565b5f6143468261432b565b9050919050565b61435e6143598261391f565b61433c565b82525050565b5f819050919050565b61437e6143798261395a565b614364565b82525050565b5f61438f828a61434d565b60148201915061439f828961434d565b6014820191506143af828861422d565b6020820191506143bf828761422d565b6020820191506143cf828661434d565b6014820191506143df828561436d565b6020820191506143ef828461436d565b60208201915081905098975050505050505050565b7f496e76616c6964207061796d656e7448617368000000000000000000000000005f82015250565b5f614438601383614186565b915061444382614404565b602082019050919050565b5f6020820190508181035f8301526144658161442c565b9050919050565b614475816138cd565b82525050565b5f60208201905061448e5f83018461446c565b92915050565b61449d8161395a565b82525050565b5f82825260208201905092915050565b50565b5f6144c15f836144a3565b91506144cc826144b3565b5f82019050919050565b5f60a0820190506144e95f83018761404d565b6144f6602083018661404d565b6145036040830185614494565b6145106060830184614494565b8181036080830152614521816144b6565b905095945050505050565b5f614537828961434d565b601482019150614547828861434d565b601482019150614557828761422d565b602082019150614567828661422d565b602082019150614577828561434d565b601482019150614587828461436d565b602082019150819050979650505050505050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e7420726566756e64206c6f636b2074696d650000000000000000602082015250565b5f6145f5603883614186565b91506146008261459b565b604082019050919050565b5f6020820190508181035f830152614622816145e9565b9050919050565b5f60608201905061463c5f83018661404d565b614649602083018561404d565b6146566040830184614494565b949350505050565b5f614669828a61436d565b602082019150614679828961436d565b602082019150614689828861434d565b601482019150614699828761434d565b6014820191506146a9828661422d565b6020820191506146b9828561422d565b6020820191506146c9828461434d565b60148201915081905098975050505050505050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b614728826146e2565b810181811067ffffffffffffffff82111715614747576147466146f2565b5b80604052505050565b5f614759613809565b9050614765828261471f565b919050565b5f60c0828403121561477f5761477e6146de565b5b61478960c0614750565b90505f614798848285016138ec565b5f8301525060206147ab84828501613946565b60208301525060406147bf84828501613946565b60408301525060606147d3848285016138ec565b60608301525060806147e7848285016138ec565b60808301525060a06147fb84828501613dac565b60a08301525092915050565b5f60c0828403121561481c5761481b613812565b5b5f6148298482850161476a565b91505092915050565b7f4d616b657220455243373231207061796d656e74206d75737420626520556e695f8201527f6e697469616c697a656400000000000000000000000000000000000000000000602082015250565b5f61488c602a83614186565b915061489782614832565b604082019050919050565b5f6020820190508181035f8301526148b981614880565b9050919050565b7f54616b6572206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f6148f4601e83614186565b91506148ff826148c0565b602082019050919050565b5f6020820190508181035f830152614921816148e8565b9050919050565b7f546f6b656e206d757374206e6f74206265207a65726f206164647265737300005f82015250565b5f61495c601e83614186565b915061496782614928565b602082019050919050565b5f6020820190508181035f83015261498981614950565b9050919050565b7f546f6b656e206164647265737320646f6573206e6f74206d617463682073656e5f8201527f6465720000000000000000000000000000000000000000000000000000000000602082015250565b5f6149ea602383614186565b91506149f582614990565b604082019050919050565b5f6020820190508181035f830152614a17816149de565b9050919050565b7f4f70657261746f72206d757374206265207468652073656e64657200000000005f82015250565b5f614a52601b83614186565b9150614a5d82614a1e565b602082019050919050565b5f6020820190508181035f830152614a7f81614a46565b9050919050565b7f54616b65722063616e6e6f74206265206120636f6e74726163740000000000005f82015250565b5f614aba601a83614186565b9150614ac582614a86565b602082019050919050565b5f6020820190508181035f830152614ae781614aae565b9050919050565b5f604082019050614b015f83018561446c565b614b0e602083018461446c565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614b4c8261395a565b9150614b578361395a565b9250828201905080821115614b6f57614b6e614b15565b5b92915050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520505f8201527f61796d656e7453656e74206f722054616b6572417070726f7665640000000000602082015250565b5f614bcf603b83614186565b9150614bda82614b75565b604082019050919050565b5f6020820190508181035f830152614bfc81614bc3565b9050919050565b7f43757272656e742074696d657374616d70206469646e277420657863656564205f8201527f7061796d656e74207072652d617070726f7665206c6f636b2074696d65000000602082015250565b5f614c5d603d83614186565b9150614c6882614c03565b604082019050919050565b5f6020820190508181035f830152614c8a81614c51565b9050919050565b7f54616b6572207061796d656e7420697320616c726561647920696e697469616c5f8201527f697a656400000000000000000000000000000000000000000000000000000000602082015250565b5f614ceb602483614186565b9150614cf682614c91565b604082019050919050565b5f6020820190508181035f830152614d1881614cdf565b9050919050565b7f5265636569766572206d757374206e6f74206265207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f614d79602183614186565b9150614d8482614d1f565b604082019050919050565b5f6020820190508181035f830152614da681614d6d565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e207a5f8201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b5f614e07602383614186565b9150614e1282614dad565b604082019050919050565b5f6020820190508181035f830152614e3481614dfb565b9050919050565b7f4554482076616c7565206d7573742062652067726561746572207468616e20645f8201527f6578206665650000000000000000000000000000000000000000000000000000602082015250565b5f614e95602683614186565b9150614ea082614e3b565b604082019050919050565b5f6020820190508181035f830152614ec281614e89565b9050919050565b5f614ed38261395a565b9150614ede8361395a565b9250828203905081811115614ef657614ef5614b15565b5b92915050565b7f4261746368207472616e7366657273206e6f7420737570706f727465640000005f82015250565b5f614f30601d83614186565b9150614f3b82614efc565b602082019050919050565b5f6020820190508181035f830152614f5d81614f24565b9050919050565b7f43616c6c6572206d75737420626520616e20454f4100000000000000000000005f82015250565b5f614f98601583614186565b9150614fa382614f64565b602082019050919050565b5f6020820190508181035f830152614fc581614f8c565b9050919050565b7f496e76616c6964207061796d656e742073746174652e204d75737420626520545f8201527f616b6572417070726f7665640000000000000000000000000000000000000000602082015250565b5f615026602c83614186565b915061503182614fcc565b604082019050919050565b5f6020820190508181035f8301526150538161501a565b9050919050565b7f4552433230207632207061796d656e7420697320616c726561647920696e69745f8201527f69616c697a656400000000000000000000000000000000000000000000000000602082015250565b5f6150b4602783614186565b91506150bf8261505a565b604082019050919050565b5f6020820190508181035f8301526150e1816150a8565b9050919050565b7f416d6f756e74206d757374206e6f74206265207a65726f0000000000000000005f82015250565b5f61511c601783614186565b9150615127826150e8565b602082019050919050565b5f6020820190508181035f83015261514981615110565b9050919050565b7f44657820666565206d757374206e6f74206265207a65726f00000000000000005f82015250565b5f615184601883614186565b915061518f82615150565b602082019050919050565b5f6020820190508181035f8301526151b181615178565b9050919050565b7f4d616b65722045524331313535207061796d656e74206d75737420626520556e5f8201527f696e697469616c697a6564000000000000000000000000000000000000000000602082015250565b5f615212602b83614186565b915061521d826151b8565b604082019050919050565b5f6020820190508181035f83015261523f81615206565b9050919050565b7f56616c7565206d7573742062652067726561746572207468616e2030000000005f82015250565b5f61527a601c83614186565b915061528582615246565b602082019050919050565b5f6020820190508181035f8301526152a78161526e565b9050919050565b5f6040820190506152c15f83018561404d565b6152ce6020830184614494565b9392505050565b6152de8161389a565b81146152e8575f80fd5b50565b5f815190506152f9816152d5565b92915050565b5f6020828403121561531457615313613812565b5b5f615321848285016152eb565b9150509291505056fea26469706673582212200d86b0f6898fb823c55626c3b02a7098bc8622606b092e0f458df6c86ce2967864736f6c63430008180033 \ No newline at end of file From 1fda81bc7474d220e931658d1698fe59fb17982d Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 25 Aug 2024 08:19:30 +0700 Subject: [PATCH 226/233] fix clippy --- mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs | 3 +-- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 4 +--- mm2src/mm2_test_helpers/src/for_tests.rs | 7 ------- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 1f627ab21e..4e294e6031 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -7,8 +7,7 @@ pub use mm2_test_helpers::for_tests::{check_my_swap_status, check_recent_swaps, MAKER_ERROR_EVENTS, MAKER_SUCCESS_EVENTS, TAKER_ERROR_EVENTS, TAKER_SUCCESS_EVENTS}; -use super::eth_docker_tests::{erc20_contract_checksum, fill_eth, fill_eth_erc20_with_private_key, geth_account, - init_p2p_context, swap_contract}; +use super::eth_docker_tests::{erc20_contract_checksum, fill_eth, fill_eth_erc20_with_private_key, swap_contract}; use bitcrypto::{dhash160, ChecksumType}; use chain::TransactionOutput; use coins::eth::addr_from_raw_pubkey; diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index a40c5b2132..6eb25ae939 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -21,13 +21,11 @@ use coins::{lp_coinfind, CoinProtocol, CoinWithDerivationMethod, CoinsContext, C Transaction, TxPreimageWithSig, ValidateNftMakerPaymentArgs, ValidateTakerFundingArgs}; use common::{block_on, now_sec}; use crypto::Secp256k1Secret; -use ethcore_transaction::Action; use ethereum_types::U256; use futures01::Future; use mm2_core::mm_ctx::MmArc; use mm2_number::{BigDecimal, BigUint}; -use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, eth_sepolia_conf, nft_dev_conf, nft_sepolia_conf, - sepolia_erc20_dev_conf}; +use mm2_test_helpers::for_tests::{erc20_dev_conf, eth_dev_conf, eth_sepolia_conf, nft_dev_conf, sepolia_erc20_dev_conf}; use serde_json::Value as Json; use std::str::FromStr; use std::thread; diff --git a/mm2src/mm2_test_helpers/src/for_tests.rs b/mm2src/mm2_test_helpers/src/for_tests.rs index 60282654bb..57084a72e2 100644 --- a/mm2src/mm2_test_helpers/src/for_tests.rs +++ b/mm2src/mm2_test_helpers/src/for_tests.rs @@ -853,13 +853,6 @@ pub fn nft_dev_conf() -> Json { }) } -/// global NFT configuration used for Sepolia testnet -pub fn nft_sepolia_conf() -> Json { - let mut conf = nft_dev_conf(); - set_chain_id(&mut conf, ETH_SEPOLIA_CHAIN_ID); - conf -} - fn set_chain_id(conf: &mut Json, chain_id: u64) { conf["chain_id"] = json!(chain_id); } From 722b8071fdd818d26496492a195a7b87eb1225dc Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 25 Aug 2024 09:21:52 +0700 Subject: [PATCH 227/233] review: remove From impl for RefundPaymentArgs --- mm2src/coins/utxo/utxo_standard.rs | 61 +++++++++++++++--------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index 2a09fe6f23..d55ce40420 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -641,7 +641,16 @@ impl MakerCoinSwapOpsV2 for UtxoStandardCoin { &self, args: RefundMakerPaymentTimelockArgs<'_>, ) -> Result { - utxo_common::refund_htlc_payment(self.clone(), args.into()).await + let args = RefundPaymentArgs { + payment_tx: args.payment_tx, + time_lock: args.time_lock, + other_pubkey: args.taker_pub, + tx_type_with_secret_hash: args.tx_type_with_secret_hash, + swap_contract_address: &None, + swap_unique_data: args.swap_unique_data, + watcher_reward: args.watcher_reward, + }; + utxo_common::refund_htlc_payment(self.clone(), args).await } async fn refund_maker_payment_v2_secret( @@ -670,7 +679,16 @@ impl TakerCoinSwapOpsV2 for UtxoStandardCoin { &self, args: RefundTakerPaymentArgs<'_>, ) -> Result { - utxo_common::refund_htlc_payment(self.clone(), args.into()).await + let args = RefundPaymentArgs { + payment_tx: args.payment_tx, + time_lock: args.time_lock, + other_pubkey: args.maker_pub, + tx_type_with_secret_hash: args.tx_type_with_secret_hash, + swap_contract_address: &None, + swap_unique_data: args.swap_unique_data, + watcher_reward: args.watcher_reward, + }; + utxo_common::refund_htlc_payment(self.clone(), args).await } async fn refund_taker_funding_secret( @@ -785,7 +803,16 @@ impl TakerCoinSwapOpsV2 for UtxoStandardCoin { &self, args: RefundTakerPaymentArgs<'_>, ) -> Result { - utxo_common::refund_htlc_payment(self.clone(), args.into()).await + let args = RefundPaymentArgs { + payment_tx: args.payment_tx, + time_lock: args.time_lock, + other_pubkey: args.maker_pub, + tx_type_with_secret_hash: args.tx_type_with_secret_hash, + swap_contract_address: &None, + swap_unique_data: args.swap_unique_data, + watcher_reward: args.watcher_reward, + }; + utxo_common::refund_htlc_payment(self.clone(), args).await } async fn gen_taker_payment_spend_preimage( @@ -1321,31 +1348,3 @@ impl UtxoTxHistoryOps for UtxoStandardCoin { *self.as_ref().history_sync_state.lock().unwrap() = new_state; } } - -impl<'a> From> for RefundPaymentArgs<'a> { - fn from(args: RefundTakerPaymentArgs<'a>) -> RefundPaymentArgs<'a> { - RefundPaymentArgs { - payment_tx: args.payment_tx, - time_lock: args.time_lock, - other_pubkey: args.maker_pub, - tx_type_with_secret_hash: args.tx_type_with_secret_hash, - swap_contract_address: &None, - swap_unique_data: args.swap_unique_data, - watcher_reward: args.watcher_reward, - } - } -} - -impl<'a> From> for RefundPaymentArgs<'a> { - fn from(args: RefundMakerPaymentTimelockArgs<'a>) -> RefundPaymentArgs<'a> { - RefundPaymentArgs { - payment_tx: args.payment_tx, - time_lock: args.time_lock, - other_pubkey: args.taker_pub, - tx_type_with_secret_hash: args.tx_type_with_secret_hash, - swap_contract_address: &None, - swap_unique_data: args.swap_unique_data, - watcher_reward: args.watcher_reward, - } - } -} From f1e6b20218111e53736627ad762ebc8cf29c40a8 Mon Sep 17 00:00:00 2001 From: laruh Date: Sun, 25 Aug 2024 10:43:47 +0700 Subject: [PATCH 228/233] provide test func changes notification in doc comms --- mm2src/coins/eth/v2_activation.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 6d37ee0912..872a8d592b 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -541,7 +541,12 @@ impl EthCoin { } /// Activate eth coin from coin config and private key build policy, -/// version 2 of the activation function, with no intrinsic tokens creation +/// version 2 of the activation function, with no intrinsic tokens creation. +/// +/// # Note +/// If you make any changes to this function, do not forget to apply the same changes +/// to the test function [eth_coin_from_conf_and_request_v2_for_test]. +/// The test function is used in configurations where the `for-tests` feature is enabled. pub async fn eth_coin_from_conf_and_request_v2( ctx: &MmArc, ticker: &str, @@ -781,6 +786,10 @@ pub(crate) async fn build_address_and_priv_key_policy( } } +/// # Note +/// If you make any changes to this function, ensure that the same updates are applied +/// to the corresponding test function [build_web3_instances_for_test]. +/// The test function is used in configurations where the `for-tests` feature is enabled. async fn build_web3_instances( ctx: &MmArc, coin_ticker: String, From f9f8d50ccab5180d1ee86e62d5c4b5745e469513 Mon Sep 17 00:00:00 2001 From: shamardy Date: Tue, 27 Aug 2024 19:11:27 +0300 Subject: [PATCH 229/233] use p2p ctx only if `komodo_proxy` is true --- mm2src/coins/eth/v2_activation.rs | 326 ++++-------------- .../tests/docker_tests/eth_docker_tests.rs | 8 +- mm2src/proxy_signature/src/lib.rs | 4 +- 3 files changed, 72 insertions(+), 266 deletions(-) diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 872a8d592b..15af41b3c2 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -542,11 +542,6 @@ impl EthCoin { /// Activate eth coin from coin config and private key build policy, /// version 2 of the activation function, with no intrinsic tokens creation. -/// -/// # Note -/// If you make any changes to this function, do not forget to apply the same changes -/// to the test function [eth_coin_from_conf_and_request_v2_for_test]. -/// The test function is used in configurations where the `for-tests` feature is enabled. pub async fn eth_coin_from_conf_and_request_v2( ctx: &MmArc, ticker: &str, @@ -786,10 +781,6 @@ pub(crate) async fn build_address_and_priv_key_policy( } } -/// # Note -/// If you make any changes to this function, ensure that the same updates are applied -/// to the corresponding test function [build_web3_instances_for_test]. -/// The test function is used in configurations where the `for-tests` feature is enabled. async fn build_web3_instances( ctx: &MmArc, coin_ticker: String, @@ -805,7 +796,6 @@ async fn build_web3_instances( let event_handlers = rpc_event_handlers_for_eth_transport(ctx, coin_ticker.clone()); - let p2p_ctx = P2PContext::fetch_from_mm_arc(ctx); let mut web3_instances = Vec::with_capacity(eth_nodes.len()); for eth_node in eth_nodes { let uri: Uri = eth_node @@ -813,51 +803,7 @@ async fn build_web3_instances( .parse() .map_err(|_| EthActivationV2Error::InvalidPayload(format!("{} could not be parsed.", eth_node.url)))?; - let transport = match uri.scheme_str() { - Some("ws") | Some("wss") => { - const TMP_SOCKET_CONNECTION: Duration = Duration::from_secs(20); - - let node = WebsocketTransportNode { uri: uri.clone() }; - - let mut websocket_transport = WebsocketTransport::with_event_handlers(node, event_handlers.clone()); - - if eth_node.komodo_proxy { - websocket_transport.proxy_sign_keypair = Some(p2p_ctx.keypair().clone()); - } - - // Temporarily start the connection loop (we close the connection once we have the client version below). - // Ideally, it would be much better to not do this workaround, which requires a lot of refactoring or - // dropping websocket support on parity nodes. - let fut = websocket_transport - .clone() - .start_connection_loop(Some(Instant::now() + TMP_SOCKET_CONNECTION)); - let settings = AbortSettings::info_on_abort(format!("connection loop stopped for {:?}", uri)); - ctx.spawner().spawn_with_settings(fut, settings); - - Web3Transport::Websocket(websocket_transport) - }, - Some("http") | Some("https") => { - let node = HttpTransportNode { - uri, - komodo_proxy: eth_node.komodo_proxy, - }; - - let komodo_proxy = node.komodo_proxy; - let mut http_transport = HttpTransport::with_event_handlers(node, event_handlers.clone()); - - if komodo_proxy { - http_transport.proxy_sign_keypair = Some(p2p_ctx.keypair().clone()); - } - - Web3Transport::from(http_transport) - }, - _ => { - return MmError::err(EthActivationV2Error::InvalidPayload(format!( - "Invalid node address '{uri}'. Only http(s) and ws(s) nodes are supported" - ))); - }, - }; - + let transport = create_transport(ctx, &uri, ð_node, &event_handlers)?; let web3 = Web3::new(transport); let version = match web3.web3().client_version().await { Ok(v) => v, @@ -882,6 +828,70 @@ async fn build_web3_instances( Ok(web3_instances) } +fn create_transport( + ctx: &MmArc, + uri: &Uri, + eth_node: &EthNode, + event_handlers: &[RpcTransportEventHandlerShared], +) -> MmResult { + match uri.scheme_str() { + Some("ws") | Some("wss") => Ok(create_websocket_transport(ctx, uri, eth_node, event_handlers)), + Some("http") | Some("https") => Ok(create_http_transport(ctx, uri, eth_node, event_handlers)), + _ => MmError::err(EthActivationV2Error::InvalidPayload(format!( + "Invalid node address '{uri}'. Only http(s) and ws(s) nodes are supported" + ))), + } +} + +fn create_websocket_transport( + ctx: &MmArc, + uri: &Uri, + eth_node: &EthNode, + event_handlers: &[RpcTransportEventHandlerShared], +) -> Web3Transport { + const TMP_SOCKET_CONNECTION: Duration = Duration::from_secs(20); + + let node = WebsocketTransportNode { uri: uri.clone() }; + + let mut websocket_transport = WebsocketTransport::with_event_handlers(node, event_handlers.to_owned()); + + if eth_node.komodo_proxy { + websocket_transport.proxy_sign_keypair = Some(P2PContext::fetch_from_mm_arc(ctx).keypair().clone()); + } + + // Temporarily start the connection loop (we close the connection once we have the client version below). + // Ideally, it would be much better to not do this workaround, which requires a lot of refactoring or + // dropping websocket support on parity nodes. + let fut = websocket_transport + .clone() + .start_connection_loop(Some(Instant::now() + TMP_SOCKET_CONNECTION)); + let settings = AbortSettings::info_on_abort(format!("connection loop stopped for {:?}", uri)); + ctx.spawner().spawn_with_settings(fut, settings); + + Web3Transport::Websocket(websocket_transport) +} + +fn create_http_transport( + ctx: &MmArc, + uri: &Uri, + eth_node: &EthNode, + event_handlers: &[RpcTransportEventHandlerShared], +) -> Web3Transport { + let node = HttpTransportNode { + uri: uri.clone(), + komodo_proxy: eth_node.komodo_proxy, + }; + + let komodo_proxy = node.komodo_proxy; + let mut http_transport = HttpTransport::with_event_handlers(node, event_handlers.to_owned()); + + if komodo_proxy { + http_transport.proxy_sign_keypair = Some(P2PContext::fetch_from_mm_arc(ctx).keypair().clone()); + } + + Web3Transport::from(http_transport) +} + #[cfg(target_arch = "wasm32")] async fn build_metamask_transport( ctx: &MmArc, @@ -946,209 +956,3 @@ fn compress_public_key(uncompressed: H520) -> MmResult MmResult { - if req.swap_contract_address == Address::default() { - return Err(EthActivationV2Error::InvalidSwapContractAddr( - "swap_contract_address can't be zero address".to_string(), - ) - .into()); - } - - if ctx.use_trading_proto_v2() { - let contracts = req.swap_v2_contracts.as_ref().ok_or_else(|| { - EthActivationV2Error::InvalidPayload( - "swap_v2_contracts must be provided when using trading protocol v2".to_string(), - ) - })?; - if contracts.maker_swap_v2_contract == Address::default() - || contracts.taker_swap_v2_contract == Address::default() - || contracts.nft_maker_swap_v2_contract == Address::default() - { - return Err(EthActivationV2Error::InvalidSwapContractAddr( - "All swap_v2_contracts addresses must be non-zero".to_string(), - ) - .into()); - } - } - - if let Some(fallback) = req.fallback_swap_contract { - if fallback == Address::default() { - return Err(EthActivationV2Error::InvalidFallbackSwapContract( - "fallback_swap_contract can't be zero address".to_string(), - ) - .into()); - } - } - - let (priv_key_policy, derivation_method) = build_address_and_priv_key_policy( - ctx, - ticker, - conf, - priv_key_build_policy, - &req.path_to_address, - req.gap_limit, - ) - .await?; - - let chain_id = conf["chain_id"].as_u64().ok_or(EthActivationV2Error::ChainIdNotSet)?; - let web3_instances = match (req.rpc_mode, &priv_key_policy) { - (EthRpcMode::Default, EthPrivKeyPolicy::Iguana(_) | EthPrivKeyPolicy::HDWallet { .. }) - | (EthRpcMode::Default, EthPrivKeyPolicy::Trezor) => { - build_web3_instances_for_test(ctx, ticker.to_string(), req.nodes.clone()).await? - }, - }; - - let required_confirmations = req - .required_confirmations - .unwrap_or_else(|| { - conf["required_confirmations"] - .as_u64() - .unwrap_or(DEFAULT_REQUIRED_CONFIRMATIONS as u64) - }) - .into(); - - let sign_message_prefix: Option = json::from_value(conf["sign_message_prefix"].clone()).ok(); - - let trezor_coin: Option = json::from_value(conf["trezor_coin"].clone()).ok(); - - let address_nonce_locks = { - let mut map = NONCE_LOCK.lock().unwrap(); - Arc::new(AsyncMutex::new( - map.entry(ticker.to_string()).or_insert_with(new_nonce_lock).clone(), - )) - }; - - let abortable_system = ctx.abortable_system.create_subsystem()?; - let coin_type = EthCoinType::Eth; - let platform_fee_estimator_state = FeeEstimatorState::init_fee_estimator(ctx, conf, &coin_type).await?; - let max_eth_tx_type = get_max_eth_tx_type_conf(ctx, conf, &coin_type).await?; - let gas_limit = extract_gas_limit_from_conf(conf) - .map_to_mm(|e| EthActivationV2Error::InternalError(format!("invalid gas_limit config {}", e)))?; - - let coin = EthCoinImpl { - priv_key_policy, - derivation_method: Arc::new(derivation_method), - coin_type, - sign_message_prefix, - swap_contract_address: req.swap_contract_address, - swap_v2_contracts: req.swap_v2_contracts, - fallback_swap_contract: req.fallback_swap_contract, - contract_supports_watchers: req.contract_supports_watchers, - decimals: ETH_DECIMALS, - ticker: ticker.to_string(), - web3_instances: AsyncMutex::new(web3_instances), - history_sync_state: Mutex::new(HistorySyncState::NotEnabled), - swap_txfee_policy: Mutex::new(SwapTxFeePolicy::Internal), - max_eth_tx_type, - ctx: ctx.weak(), - required_confirmations, - chain_id, - trezor_coin, - logs_block_range: conf["logs_block_range"].as_u64().unwrap_or(DEFAULT_LOGS_BLOCK_RANGE), - address_nonce_locks, - erc20_tokens_infos: Default::default(), - nfts_infos: Default::default(), - platform_fee_estimator_state, - gas_limit, - abortable_system, - }; - - let coin = EthCoin(Arc::new(coin)); - coin.spawn_balance_stream_if_enabled(ctx) - .await - .map_err(EthActivationV2Error::FailedSpawningBalanceEvents)?; - - Ok(coin) -} - -/// Builds web3 instances without using [P2PContext] -#[cfg(all(feature = "for-tests", not(target_arch = "wasm32")))] -async fn build_web3_instances_for_test( - ctx: &MmArc, - coin_ticker: String, - mut eth_nodes: Vec, -) -> MmResult, EthActivationV2Error> { - if eth_nodes.is_empty() { - return MmError::err(EthActivationV2Error::AtLeastOneNodeRequired); - } - - let mut rng = small_rng(); - eth_nodes.as_mut_slice().shuffle(&mut rng); - drop_mutability!(eth_nodes); - - let event_handlers = rpc_event_handlers_for_eth_transport(ctx, coin_ticker.clone()); - - let mut web3_instances = Vec::with_capacity(eth_nodes.len()); - for eth_node in eth_nodes { - let uri: Uri = eth_node - .url - .parse() - .map_err(|_| EthActivationV2Error::InvalidPayload(format!("{} could not be parsed.", eth_node.url)))?; - - let transport = match uri.scheme_str() { - Some("ws") | Some("wss") => { - const TMP_SOCKET_CONNECTION: Duration = Duration::from_secs(20); - let node = WebsocketTransportNode { uri: uri.clone() }; - let websocket_transport = WebsocketTransport::with_event_handlers(node, event_handlers.clone()); - - // Temporarily start the connection loop (we close the connection once we have the client version below). - // Ideally, it would be much better to not do this workaround, which requires a lot of refactoring or - // dropping websocket support on parity nodes. - let fut = websocket_transport - .clone() - .start_connection_loop(Some(Instant::now() + TMP_SOCKET_CONNECTION)); - let settings = AbortSettings::info_on_abort(format!("connection loop stopped for {:?}", uri)); - ctx.spawner().spawn_with_settings(fut, settings); - - Web3Transport::Websocket(websocket_transport) - }, - Some("http") | Some("https") => { - let node = HttpTransportNode { - uri, - komodo_proxy: eth_node.komodo_proxy, - }; - - let http_transport = HttpTransport::with_event_handlers(node, event_handlers.clone()); - - Web3Transport::from(http_transport) - }, - _ => { - return MmError::err(EthActivationV2Error::InvalidPayload(format!( - "Invalid node address '{uri}'. Only http(s) and ws(s) nodes are supported" - ))); - }, - }; - - let web3 = Web3::new(transport); - let version = match web3.web3().client_version().await { - Ok(v) => v, - Err(e) => { - error!("Couldn't get client version for url {}: {}", eth_node.url, e); - continue; - }, - }; - - web3_instances.push(Web3Instance { - web3, - is_parity: version.contains("Parity") || version.contains("parity"), - }); - } - - if web3_instances.is_empty() { - return Err( - EthActivationV2Error::UnreachableNodes("Failed to get client version for all nodes".to_string()).into(), - ); - } - - Ok(web3_instances) -} diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 6eb25ae939..d4237a6a7b 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -7,7 +7,7 @@ use super::docker_tests_common::{random_secp256k1_secret, ERC1155_TEST_ABI, ERC7 use crate::common::Future01CompatExt; use bitcrypto::{dhash160, sha256}; use coins::eth::gas_limit::ETH_MAX_TRADE_GAS; -use coins::eth::v2_activation::{eth_coin_from_conf_and_request_v2_for_test, EthActivationV2Request, EthNode}; +use coins::eth::v2_activation::{eth_coin_from_conf_and_request_v2, EthActivationV2Request, EthNode}; use coins::eth::{checksum_address, eth_addr_to_hex, eth_coin_from_conf_and_request, EthCoin, EthCoinType, EthPrivKeyBuildPolicy, SignedEthTx, SwapV2Contracts, ERC20_ABI}; use coins::nft::nft_structs::{Chain, ContractType, NftInfo}; @@ -363,7 +363,7 @@ fn global_nft_with_random_privkey( path_to_address: Default::default(), gap_limit: None, }; - let coin = block_on(eth_coin_from_conf_and_request_v2_for_test( + let coin = block_on(eth_coin_from_conf_and_request_v2( &MM_CTX1, nft_ticker.as_str(), &nft_dev_conf(), @@ -432,7 +432,7 @@ fn sepolia_coin_from_privkey(ctx: &MmArc, secret: &'static str, ticker: &str, co path_to_address: Default::default(), gap_limit: None, }; - let coin = block_on(eth_coin_from_conf_and_request_v2_for_test( + let coin = block_on(eth_coin_from_conf_and_request_v2( ctx, ticker, conf, @@ -1428,7 +1428,7 @@ fn eth_coin_v2_activation_with_random_privkey( path_to_address: Default::default(), gap_limit: None, }; - let coin = block_on(eth_coin_from_conf_and_request_v2_for_test( + let coin = block_on(eth_coin_from_conf_and_request_v2( &MM_CTX1, ticker, conf, diff --git a/mm2src/proxy_signature/src/lib.rs b/mm2src/proxy_signature/src/lib.rs index 86f57a3431..f4ae2393a0 100644 --- a/mm2src/proxy_signature/src/lib.rs +++ b/mm2src/proxy_signature/src/lib.rs @@ -74,7 +74,9 @@ impl ProxySign { return false; } - let Ok(public_key) = PublicKey::try_decode_protobuf(&self.raw_message.public_key_encoded) else { return false }; + let Ok(public_key) = PublicKey::try_decode_protobuf(&self.raw_message.public_key_encoded) else { + return false; + }; if self.address != public_key.to_peer_id().to_string() { return false; From b744a1d9afc566a489f522a4dac01be181aecdcc Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 28 Aug 2024 12:25:10 +0700 Subject: [PATCH 230/233] correct GETH_NONCE_LOCK in geth_erc1155_balance and ERC20 ticker in erc20 tests --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index d4237a6a7b..51a23aa2c8 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -209,7 +209,7 @@ fn mint_erc1155(to_addr: Address, token_id: U256, amount: U256) { } fn geth_erc1155_balance(wallet_addr: Address, token_id: U256) -> U256 { - let _guard = SEPOLIA_NONCE_LOCK.lock().unwrap(); + let _guard = GETH_NONCE_LOCK.lock().unwrap(); let erc1155_contract = Contract::from_json(GETH_WEB3.eth(), geth_erc1155_contract(), ERC1155_TEST_ABI.as_bytes()).unwrap(); block_on(erc1155_contract.query( @@ -1749,8 +1749,8 @@ fn taker_send_approve_and_spend_erc20() { // sepolia test thread::sleep(Duration::from_secs(9)); let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); - let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, erc20_conf, true); - let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, erc20_conf, true); + let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); + let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); let taker_secret = vec![0; 32]; let taker_secret_hash = sha256(&taker_secret).to_vec(); @@ -1941,8 +1941,8 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_erc20() { // sepolia test thread::sleep(Duration::from_secs(28)); let erc20_conf = &sepolia_erc20_dev_conf(&sepolia_erc20_contract_checksum()); - let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ETH, erc20_conf, true); - let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ETH, erc20_conf, true); + let taker_coin = get_or_create_sepolia_coin(&MM_CTX1, SEPOLIA_TAKER_PRIV, ERC20, erc20_conf, true); + let maker_coin = get_or_create_sepolia_coin(&MM_CTX, SEPOLIA_MAKER_PRIV, ERC20, erc20_conf, true); let taker_secret = vec![0; 32]; let taker_secret_hash = sha256(&taker_secret).to_vec(); From 2381b7ded8c83d19fe6462e0a09ab923e1891d2d Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 28 Aug 2024 14:53:46 +0700 Subject: [PATCH 231/233] review: provide check_decoded_length --- mm2src/coins/eth/eth_swap_v2.rs | 34 ++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index dda270b23f..a01015ca74 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -608,6 +608,7 @@ impl EthCoin { let function = TAKER_SWAP_V2.function(TAKER_PAYMENT_APPROVE)?; let data = match self.coin_type { EthCoinType::Eth => { + check_decoded_length(&decoded, 7)?; let dex_fee = match &decoded[1] { Token::Uint(value) => value, _ => return Err(PrepareTxDataError::Internal("Invalid token type for dex fee".into())), @@ -630,15 +631,18 @@ impl EthCoin { Token::Address(token_address), // should be zero address Address::default() ])? }, - EthCoinType::Erc20 { .. } => function.encode_input(&[ - decoded[0].clone(), // id from erc20TakerPayment - decoded[1].clone(), // amount from erc20TakerPayment - decoded[2].clone(), // dexFee from erc20TakerPayment - decoded[4].clone(), // receiver from erc20TakerPayment - Token::FixedBytes(args.taker_secret_hash.to_vec()), - Token::FixedBytes(args.maker_secret_hash.to_vec()), - Token::Address(token_address), // erc20 token address from EthCoinType::Erc20 - ])?, + EthCoinType::Erc20 { .. } => { + check_decoded_length(&decoded, 9)?; + function.encode_input(&[ + decoded[0].clone(), // id from erc20TakerPayment + decoded[1].clone(), // amount from erc20TakerPayment + decoded[2].clone(), // dexFee from erc20TakerPayment + decoded[4].clone(), // receiver from erc20TakerPayment + Token::FixedBytes(args.taker_secret_hash.to_vec()), + Token::FixedBytes(args.maker_secret_hash.to_vec()), + Token::Address(token_address), // erc20 token address from EthCoinType::Erc20 + ])? + }, EthCoinType::Nft { .. } => { return Err(PrepareTxDataError::Internal("EthCoinType must be ETH or ERC20".into())) }, @@ -653,6 +657,7 @@ impl EthCoin { decoded: Vec, token_address: Address, ) -> Result, PrepareTxDataError> { + check_decoded_length(&decoded, 7)?; let function = TAKER_SWAP_V2.function("spendTakerPayment")?; let taker_address = public_to_address(args.taker_pub); let data = function.encode_input(&[ @@ -944,3 +949,14 @@ pub(crate) enum PaymentStatusErr { #[display(fmt = "Invalid data error: {}", _0)] InvalidData(String), } + +fn check_decoded_length(decoded: &Vec, expected_len: usize) -> Result<(), PrepareTxDataError> { + if decoded.len() != expected_len { + return Err(PrepareTxDataError::Internal(format!( + "Invalid number of tokens in decoded. Expected {}, found {}", + expected_len, + decoded.len() + ))); + } + Ok(()) +} From 1faea01ddcc82f5c196055a50122f37ccc3d8b42 Mon Sep 17 00:00:00 2001 From: laruh Date: Wed, 28 Aug 2024 15:24:11 +0700 Subject: [PATCH 232/233] ignore taker sepolia tests --- mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 51a23aa2c8..3a898b0f2f 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -1450,6 +1450,7 @@ fn eth_coin_v2_activation_with_random_privkey( coin } +#[ignore] #[test] fn send_and_refund_taker_funding_by_secret_eth() { // sepolia test @@ -1511,6 +1512,7 @@ fn send_and_refund_taker_funding_by_secret_eth() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } +#[ignore] #[test] fn send_and_refund_taker_funding_by_secret_erc20() { thread::sleep(Duration::from_secs(130)); @@ -1572,6 +1574,7 @@ fn send_and_refund_taker_funding_by_secret_erc20() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 200); } +#[ignore] #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { thread::sleep(Duration::from_secs(12)); @@ -1636,6 +1639,7 @@ fn send_and_refund_taker_funding_exceed_pre_approve_timelock_eth() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } +#[ignore] #[test] fn taker_send_approve_and_spend_eth() { // sepolia test @@ -1744,6 +1748,7 @@ fn taker_send_approve_and_spend_eth() { block_on(taker_coin.wait_for_taker_payment_spend(&spend_tx, 0u64, payment_time_lock)).unwrap(); } +#[ignore] #[test] fn taker_send_approve_and_spend_erc20() { // sepolia test @@ -1853,6 +1858,7 @@ fn taker_send_approve_and_spend_erc20() { block_on(taker_coin.wait_for_taker_payment_spend(&spend_tx, 0u64, payment_time_lock)).unwrap(); } +#[ignore] #[test] fn send_and_refund_taker_funding_exceed_payment_timelock_eth() { // sepolia test @@ -1936,6 +1942,7 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_eth() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } +#[ignore] #[test] fn send_and_refund_taker_funding_exceed_payment_timelock_erc20() { // sepolia test @@ -2021,6 +2028,7 @@ fn send_and_refund_taker_funding_exceed_payment_timelock_erc20() { wait_for_confirmations(&taker_coin, &funding_tx_refund, 100); } +#[ignore] #[test] fn send_and_refund_taker_funding_exceed_pre_approve_timelock_erc20() { // sepolia test From 6dd0fc296e0b2a2afcc0c377875ef9db9b86dd1a Mon Sep 17 00:00:00 2001 From: laruh Date: Thu, 29 Aug 2024 11:18:44 +0700 Subject: [PATCH 233/233] review: provide smart contract methods links --- mm2src/coins/eth/eth_swap_v2.rs | 44 +++++---------------------------- 1 file changed, 6 insertions(+), 38 deletions(-) diff --git a/mm2src/coins/eth/eth_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2.rs index a01015ca74..0d61ac6004 100644 --- a/mm2src/coins/eth/eth_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2.rs @@ -488,15 +488,7 @@ impl EthCoin { } } - /// Prepares data for EtomicSwapTakerV2 contract `ethTakerPayment` method - /// function ethTakerPayment( - /// bytes32 id, - /// uint256 dexFee, - /// address receiver, - /// bytes32 takerSecretHash, - /// bytes32 makerSecretHash, - /// uint32 preApproveLockTime, - /// uint32 paymentLockTime + /// Prepares data for EtomicSwapTakerV2 contract [ethTakerPayment](https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapTakerV2.sol#L44) method async fn prepare_taker_eth_funding_data(&self, args: &TakerFundingArgs) -> Result, PrepareTxDataError> { let function = TAKER_SWAP_V2.function(ETH_TAKER_PAYMENT)?; let id = self.etomic_swap_id_v2(args.payment_time_lock, &args.maker_secret_hash); @@ -512,17 +504,7 @@ impl EthCoin { Ok(data) } - /// Prepares data for EtomicSwapTakerV2 contract `erc20TakerPayment` method - /// function erc20TakerPayment( - /// bytes32 id, - /// uint256 amount, - /// uint256 dexFee, - /// address tokenAddress, - /// address receiver, - /// bytes32 takerSecretHash, - /// bytes32 makerSecretHash, - /// uint32 preApproveLockTime, - /// uint32 paymentLockTime + /// Prepares data for EtomicSwapTakerV2 contract [erc20TakerPayment](https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapTakerV2.sol#L83) method async fn prepare_taker_erc20_funding_data( &self, args: &TakerFundingArgs, @@ -544,14 +526,7 @@ impl EthCoin { Ok(data) } - /// Prepares data for EtomicSwapTakerV2 contract `refundTakerPaymentTimelock` method - /// function refundMakerPaymentTimelock( - /// bytes32 id, - /// uint256 amount, - /// address taker, - /// bytes32 takerSecretHash, - /// bytes32 makerSecretHash, - /// address tokenAddress + /// Prepares data for EtomicSwapTakerV2 contract [refundTakerPaymentTimelock](https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapTakerV2.sol#L208) method async fn prepare_taker_refund_payment_timelock_data( &self, args: TakerRefundArgs, @@ -570,15 +545,7 @@ impl EthCoin { Ok(data) } - /// Prepares data for EtomicSwapTakerV2 contract `refundTakerPaymentSecret` method - /// function refundTakerPaymentSecret( - /// bytes32 id, - /// uint256 amount, - /// uint256 dexFee, - /// address maker, - /// bytes32 takerSecret, - /// bytes32 makerSecretHash, - /// address tokenAddress + /// Prepares data for EtomicSwapTakerV2 contract [refundTakerPaymentSecret](https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapTakerV2.sol#L267) method async fn prepare_taker_refund_payment_secret_data( &self, args: &TakerRefundArgs, @@ -597,7 +564,7 @@ impl EthCoin { Ok(data) } - /// This function constructs the encoded transaction input data required to approve the taker payment. + /// This function constructs the encoded transaction input data required to approve the taker payment ([takerPaymentApprove](https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapTakerV2.sol#L128)). /// The `decoded` parameter should contain the transaction input data from the `ethTakerPayment` or `erc20TakerPayment` function of the EtomicSwapTakerV2 contract. async fn prepare_taker_payment_approve_data( &self, @@ -650,6 +617,7 @@ impl EthCoin { Ok(data) } + /// Prepares data for EtomicSwapTakerV2 contract [spendTakerPayment](https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapTakerV2.sol#L164) method async fn prepare_spend_taker_payment_data( &self, args: &GenTakerPaymentSpendArgs<'_, Self>,