diff --git a/.prettierignore b/.prettierignore index 4971c404b..11631ff81 100644 --- a/.prettierignore +++ b/.prettierignore @@ -9,4 +9,5 @@ node_modules/ typechain/ # files +src/test/smart-wallet/utils/AABenchmarkArtifacts.sol coverage.json diff --git a/contracts/lib/TWStrings.sol b/contracts/lib/TWStrings.sol index b04e5f05a..0b48fac3e 100644 --- a/contracts/lib/TWStrings.sol +++ b/contracts/lib/TWStrings.sol @@ -64,4 +64,132 @@ library TWStrings { require(value == 0, "Strings: hex length insufficient"); return string(buffer); } + + /// @dev Returns the hexadecimal representation of `value`. + /// The output is prefixed with "0x", encoded using 2 hexadecimal digits per byte, + /// and the alphabets are capitalized conditionally according to + /// https://eips.ethereum.org/EIPS/eip-55 + function toHexStringChecksummed(address value) internal pure returns (string memory str) { + str = toHexString(value); + /// @solidity memory-safe-assembly + assembly { + let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...` + let o := add(str, 0x22) + let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... ` + let t := shl(240, 136) // `0b10001000 << 240` + for { + let i := 0 + } 1 { + + } { + mstore(add(i, i), mul(t, byte(i, hashed))) + i := add(i, 1) + if eq(i, 20) { + break + } + } + mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask))))) + o := add(o, 0x20) + mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask))))) + } + } + + /// @dev Returns the hexadecimal representation of `value`. + /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte. + function toHexString(address value) internal pure returns (string memory str) { + str = toHexStringNoPrefix(value); + /// @solidity memory-safe-assembly + assembly { + let strLength := add(mload(str), 2) // Compute the length. + mstore(str, 0x3078) // Write the "0x" prefix. + str := sub(str, 2) // Move the pointer. + mstore(str, strLength) // Write the length. + } + } + + /// @dev Returns the hexadecimal representation of `value`. + /// The output is encoded using 2 hexadecimal digits per byte. + function toHexStringNoPrefix(address value) internal pure returns (string memory str) { + /// @solidity memory-safe-assembly + assembly { + str := mload(0x40) + + // Allocate the memory. + // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length, + // 0x02 bytes for the prefix, and 0x28 bytes for the digits. + // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80. + mstore(0x40, add(str, 0x80)) + + // Store "0123456789abcdef" in scratch space. + mstore(0x0f, 0x30313233343536373839616263646566) + + str := add(str, 2) + mstore(str, 40) + + let o := add(str, 0x20) + mstore(add(o, 40), 0) + + value := shl(96, value) + + // We write the string from rightmost digit to leftmost digit. + // The following is essentially a do-while loop that also handles the zero case. + for { + let i := 0 + } 1 { + + } { + let p := add(o, add(i, i)) + let temp := byte(i, value) + mstore8(add(p, 1), mload(and(temp, 15))) + mstore8(p, mload(shr(4, temp))) + i := add(i, 1) + if eq(i, 20) { + break + } + } + } + } + + /// @dev Returns the hex encoded string from the raw bytes. + /// The output is encoded using 2 hexadecimal digits per byte. + function toHexString(bytes memory raw) internal pure returns (string memory str) { + str = toHexStringNoPrefix(raw); + /// @solidity memory-safe-assembly + assembly { + let strLength := add(mload(str), 2) // Compute the length. + mstore(str, 0x3078) // Write the "0x" prefix. + str := sub(str, 2) // Move the pointer. + mstore(str, strLength) // Write the length. + } + } + + /// @dev Returns the hex encoded string from the raw bytes. + /// The output is encoded using 2 hexadecimal digits per byte. + function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory str) { + /// @solidity memory-safe-assembly + assembly { + let length := mload(raw) + str := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix. + mstore(str, add(length, length)) // Store the length of the output. + + // Store "0123456789abcdef" in scratch space. + mstore(0x0f, 0x30313233343536373839616263646566) + + let o := add(str, 0x20) + let end := add(raw, length) + + for { + + } iszero(eq(raw, end)) { + + } { + raw := add(raw, 1) + mstore8(add(o, 1), mload(and(mload(raw), 15))) + mstore8(o, mload(and(shr(4, mload(raw)), 15))) + o := add(o, 2) + } + mstore(o, 0) // Zeroize the slot after the string. + mstore(0x40, add(o, 0x20)) // Allocate the memory. + } + } } diff --git a/foundry.toml b/foundry.toml index aa51c2565..d24113933 100644 --- a/foundry.toml +++ b/foundry.toml @@ -38,8 +38,9 @@ remappings = [ 'erc721a-upgradeable/=lib/ERC721A-Upgradeable/', 'erc721a/=lib/ERC721A/', '@thirdweb-dev/dynamic-contracts/=lib/dynamic-contracts/', - 'lib/sstore2=lib/dynamic-contracts/lib/sstore2/' + 'lib/sstore2=lib/dynamic-contracts/lib/sstore2/', ] +fs_permissions = [{ access = "read-write", path = "./src/test/smart-wallet/utils"}] src = 'contracts' test = 'src/test' verbosity = 0 diff --git a/package.json b/package.json index 926367699..558343bd7 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,8 @@ "forge:build": "forge build", "forge:test": "forge test", "gas": "forge test --mc Benchmark --gas-report > gasreport.txt", - "forge:snapshot": "forge snapshot --check" + "forge:snapshot": "forge snapshot --check", + "aabenchmark": "forge test --mc AABenchmarkPrepare && forge test --mc ProfileThirdwebAccount -vvv" }, "dependencies": {} } diff --git a/src/test/smart-wallet/utils/AABenchmarkArtifacts.sol b/src/test/smart-wallet/utils/AABenchmarkArtifacts.sol new file mode 100644 index 000000000..1a59f5bea --- /dev/null +++ b/src/test/smart-wallet/utils/AABenchmarkArtifacts.sol @@ -0,0 +1,14 @@ + +pragma solidity ^0.8.0; +interface ThirdwebAccountFactory { + function createAccount(address _admin, bytes calldata _data) external returns (address); + function getAddress(address _adminSigner, bytes calldata _data) external view returns (address); +} +interface ThirdwebAccount { + function execute(address _target, uint256 _value, bytes calldata _calldata) external; +} +address constant THIRDWEB_ACCOUNT_FACTORY_ADDRESS = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; +address constant THIRDWEB_ACCOUNT_IMPL_ADDRESS = 0xffD4505B3452Dc22f8473616d50503bA9E1710Ac; +bytes constant THIRDWEB_ACCOUNT_FACTORY_BYTECODE = hex"608060405234801561001057600080fd5b50600436106101735760003560e01c80639387a380116100de578063c3c5a54711610097578063d8fd8f4411610071578063d8fd8f4414610482578063e68a7c3b146104b2578063e8a3d485146104e2578063f399e22e1461050057610173565b8063c3c5a54714610406578063ca15c87314610436578063d547741f1461046657610173565b80639387a38014610332578063938e3d7b1461034e578063a217fddf1461036a578063a32fa5b314610388578063a65d69d4146103b8578063ac9650d8146103d657610173565b806336568abe1161013057806336568abe1461024c57806358451f971461026857806383a03f8c146102865780638878ed33146102a25780639010d07c146102d257806391d148541461030257610173565b806308e93d0a146101785780630b61e12b146101965780630e6254fd146101b257806311464fbe146101e2578063248a9ca3146102005780632f2ff15d14610230575b600080fd5b61018061051c565b60405161018d9190612888565b60405180910390f35b6101b060048036038101906101ab9190612920565b610536565b005b6101cc60048036038101906101c79190612960565b610649565b6040516101d99190612888565b60405180910390f35b6101ea6106a2565b6040516101f7919061299c565b60405180910390f35b61021a600480360381019061021591906129b7565b6106c6565b60405161022791906129f3565b60405180910390f35b61024a60048036038101906102459190612a0e565b6106ec565b005b61026660048036038101906102619190612a0e565b6107ce565b005b610270610851565b60405161027d9190612a67565b60405180910390f35b6102a0600480360381019061029b91906129b7565b61086b565b005b6102bc60048036038101906102b79190612ae7565b610919565b6040516102c9919061299c565b60405180910390f35b6102ec60048036038101906102e79190612b73565b6109a0565b6040516102f9919061299c565b60405180910390f35b61031c60048036038101906103179190612a0e565b610b76565b6040516103299190612bce565b60405180910390f35b61034c60048036038101906103479190612920565b610be7565b005b61036860048036038101906103639190612d2a565b610cfa565b005b610372610d4d565b60405161037f91906129f3565b60405180910390f35b6103a2600480360381019061039d9190612a0e565b610d54565b6040516103af9190612bce565b60405180910390f35b6103c0610e3a565b6040516103cd919061299c565b60405180910390f35b6103f060048036038101906103eb9190612dc9565b610e5e565b6040516103fd9190612f60565b60405180910390f35b610420600480360381019061041b9190612960565b610f6a565b60405161042d9190612bce565b60405180910390f35b610450600480360381019061044b91906129b7565b610f90565b60405161045d9190612a67565b60405180910390f35b610480600480360381019061047b9190612a0e565b61108f565b005b61049c60048036038101906104979190612ae7565b6110ca565b6040516104a9919061299c565b60405180910390f35b6104cc60048036038101906104c79190612f82565b6112ab565b6040516104d99190612888565b60405180910390f35b6104ea61140f565b6040516104f79190613017565b60405180910390f35b61051a60048036038101906105159190613039565b6114aa565b005b6060610531610529611659565b600001611668565b905090565b60003390506105458183611689565b610584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057b906130e1565b60405180910390fd5b60006105e082610592611659565b60020160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206116f090919063ffffffff16565b90508015610643578373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f12146497b3b826918ec47f0cac7272a09ed06b30c16c030e99ec48ff5dd60b4760405160405180910390a35b50505050565b606061069b610656611659565b60020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611668565b9050919050565b7f000000000000000000000000ffd4505b3452dc22f8473616d50503ba9e1710ac81565b60006106d0611720565b6001016000838152602001908152602001600020549050919050565b6107196106f7611720565b60010160008481526020019081526020016000205461071461172f565b611737565b610721611720565b600001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156107c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b79061314d565b60405180910390fd5b6107ca8282611831565b5050565b8073ffffffffffffffffffffffffffffffffffffffff166107ed61172f565b73ffffffffffffffffffffffffffffffffffffffff1614610843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083a906131b9565b60405180910390fd5b61084d8282611849565b5050565b600061086661085e611659565b600001611861565b905090565b600033905061087a8183611689565b6108b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108b0906130e1565b60405180910390fd5b6108d6816108c5611659565b6000016116f090919063ffffffff16565b610915576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090c9061324b565b60405180910390fd5b5050565b60008061096a8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611876565b90506109967f000000000000000000000000ffd4505b3452dc22f8473616d50503ba9e1710ac826118a9565b9150509392505050565b6000806109ab6118be565b6000016000858152602001908152602001600020600001549050600080600090505b82811015610b6c57600073ffffffffffffffffffffffffffffffffffffffff166109f56118be565b6000016000888152602001908152602001600020600101600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ad05784821415610abc57610a696118be565b6000016000878152602001908152602001600020600101600082815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169350505050610b70565b600182610ac9919061329a565b9150610b58565b610adb866000610b76565b8015610b425750610aea6118be565b600001600087815260200190815260200160002060020160008073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481145b15610b5757600182610b54919061329a565b91505b5b600181610b65919061329a565b90506109cd565b5050505b92915050565b6000610b80611720565b600001600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000339050610bf68183611689565b610c35576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2c906130e1565b60405180910390fd5b6000610c9182610c43611659565b60020160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206118cd90919063ffffffff16565b90508015610cf4578373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f98d1ebbe00ae92a5de96a0f49742a8afa89f42363592bc2e7cfaaed68b45e7a660405160405180910390a35b50505050565b610d026118fd565b610d41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d389061333c565b60405180910390fd5b610d4a81611911565b50565b6000801b81565b6000610d5e611720565b600001600084815260200190815260200160002060008073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610e2f57610dc9611720565b600001600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050610e34565b600190505b92915050565b7f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d278981565b60608282905067ffffffffffffffff811115610e7d57610e7c612bff565b5b604051908082528060200260200182016040528015610eb057816020015b6060815260200190600190039081610e9b5790505b50905060005b83839050811015610f6357610f3230858584818110610ed857610ed761335c565b5b9050602002810190610eea919061339a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611a06565b828281518110610f4557610f4461335c565b5b60200260200101819052508080610f5b906133fd565b915050610eb6565b5092915050565b6000610f8982610f78611659565b600001611a3390919063ffffffff16565b9050919050565b600080610f9b6118be565b600001600084815260200190815260200160002060000154905060005b8181101561106857600073ffffffffffffffffffffffffffffffffffffffff16610fe06118be565b6000016000868152602001908152602001600020600101600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461105457600183611051919061329a565b92505b600181611061919061329a565b9050610fb8565b50611074836000610b76565b1561108957600182611086919061329a565b91505b50919050565b6110bc61109a611720565b6001016000848152602001908152602001600020546110b761172f565b611737565b6110c68282611849565b5050565b6000807f000000000000000000000000ffd4505b3452dc22f8473616d50503ba9e1710ac905060006111408686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611876565b9050600061114e83836118a9565b905060008173ffffffffffffffffffffffffffffffffffffffff163b111561117b578093505050506112a4565b6111858383611a63565b90507f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d278973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611237576111f7816111e6611659565b6000016116f090919063ffffffff16565b611236576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161122d9061324b565b60405180910390fd5b5b61124381888888611b20565b8673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fac631f3001b55ea1509cf3d7e74898f85392a61a76e8149181ae1259622dabc860405160405180910390a38093505050505b9392505050565b606081831080156112ce57506112ca6112c2611659565b600001611861565b8211155b61130d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611304906134b8565b60405180910390fd5b6000838361131b91906134d8565b9050838361132991906134d8565b67ffffffffffffffff81111561134257611341612bff565b5b6040519080825280602002602001820160405280156113705781602001602082028036833780820191505090505b50915060005b81811015611407576113a6858261138d919061329a565b611395611659565b600001611b9790919063ffffffff16565b8382815181106113b9576113b861335c565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600181611400919061329a565b9050611376565b505092915050565b6060611419611bb1565b60000180546114279061353b565b80601f01602080910402602001604051908101604052809291908181526020018280546114539061353b565b80156114a05780601f10611475576101008083540402835291602001916114a0565b820191906000526020600020905b81548152906001019060200180831161148357829003601f168201915b5050505050905090565b60006114b4611bc0565b60000160009054906101000a900460ff16905060006114d1611bc0565b60000160019054906101000a900460ff1690506000811590508080156114fa575060018360ff16105b8061151a575061150930611bcf565b158015611519575060018360ff16145b5b611559576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611550906135df565b60405180910390fd5b6001611563611bc0565b60000160006101000a81548160ff021916908360ff16021790555080156115a957600161158e611bc0565b60000160016101000a81548160ff0219169083151502179055505b6115b66000801b86611831565b6115bf84611911565b80156116225760006115cf611bc0565b60000160016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516116199190613651565b60405180910390a15b5050505050565b6000807f322cf19c484104d3b1a9c2982ebae869ede3fa5f6c4703ca41b9a48c76ee030060001b90508091505090565b6000611663611bf2565b905090565b6060600061167883600001611c22565b905060608190508092505050919050565b6000806116b67f000000000000000000000000ffd4505b3452dc22f8473616d50503ba9e1710ac846118a9565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161491505092915050565b6000611718836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611c7e565b905092915050565b600061172a611cee565b905090565b600033905090565b61173f611720565b600001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661182d576117c38173ffffffffffffffffffffffffffffffffffffffff166014611d1e565b6117d18360001c6020611d1e565b6040516020016117e2929190613740565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118249190613017565b60405180910390fd5b5050565b61183b8282611f5a565b6118458282612032565b5050565b6118538282612162565b61185d828261223b565b5050565b600061186f82600001612354565b9050919050565b6000828260405160200161188b9291906137c4565b60405160208183030381529060405280519060200120905092915050565b60006118b6838330612365565b905092915050565b60006118c86123c6565b905090565b60006118f5836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61242f565b905092915050565b600061190c6000801b33610b76565b905090565b600061191b611bb1565b60000180546119299061353b565b80601f01602080910402602001604051908101604052809291908181526020018280546119559061353b565b80156119a25780601f10611977576101008083540402835291602001916119a2565b820191906000526020600020905b81548152906001019060200180831161198557829003601f168201915b50505050509050816119b2611bb1565b60000190805190602001906119c89291906126f5565b507fc9c7c3fe08b88b4df9d4d47ef47d2c43d55c025a0ba88ca442580ed9e7348a1681836040516119fa9291906137f4565b60405180910390a15050565b6060611a2b8383604051806060016040528060278152602001613b0960279139612543565b905092915050565b6000611a5b836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612610565b905092915050565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008360601b60e81c176000526e5af43d82803e903d91602b57fd5bf38360781b1760205281603760096000f59050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611b1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1190613877565b60405180910390fd5b92915050565b8373ffffffffffffffffffffffffffffffffffffffff1663cf7a1d77843085856040518563ffffffff1660e01b8152600401611b5f94939291906138c4565b600060405180830381600087803b158015611b7957600080fd5b505af1158015611b8d573d6000803e3d6000fd5b5050505050505050565b6000611ba68360000183612633565b60001c905092915050565b6000611bbb61265e565b905090565b6000611bca611629565b905090565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000807f82f5b3e5f5ca1c04b70bced106a2c3b72d9cb53ebbafb3cad0740983db74290060001b90508091505090565b606081600001805480602002602001604051908101604052809291908181526020018280548015611c7257602002820191906000526020600020905b815481526020019060010190808311611c5e575b50505050509050919050565b6000611c8a8383612610565b611ce3578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611ce8565b600090505b92915050565b6000807f0a7b0f5c59907924802379ebe98cdc23e2ee7820f63d30126e10b3752010e50060001b90508091505090565b606060006002836002611d319190613904565b611d3b919061329a565b67ffffffffffffffff811115611d5457611d53612bff565b5b6040519080825280601f01601f191660200182016040528015611d865781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611dbe57611dbd61335c565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611e2257611e2161335c565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002611e629190613904565b611e6c919061329a565b90505b6001811115611f0c577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110611eae57611ead61335c565b5b1a60f81b828281518110611ec557611ec461335c565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080611f059061395e565b9050611e6f565b5060008414611f50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f47906139d4565b60405180910390fd5b8091505092915050565b6001611f64611720565b600001600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611fd461172f565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600061203c6118be565b600001600084815260200190815260200160002060000154905060016120606118be565b60000160008581526020019081526020016000206000016000828254612086919061329a565b92505081905550816120966118be565b6000016000858152602001908152602001600020600101600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806121056118be565b600001600085815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050565b61216c8282611737565b612174611720565b600001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81549060ff02191690556121dd61172f565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60006122456118be565b600001600084815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506122a46118be565b6000016000848152602001908152602001600020600101600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556122f76118be565b600001600084815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009055505050565b600081600001805490509050919050565b60006040518260388201526f5af43d82803e903d91602b57fd5bf3ff6024820152846014820152733d602d80600a3d3981f3363d3d373d3d3d363d7381528360588201526037600c8201206078820152605560438201209150509392505050565b60008060ff60001b1960017f0c4ba382c0009cf238e4c1ca1a52f51c61e6248a70bdfb34e5ed49d5578a5c0c60001c6123ff91906134d8565b60405160200161240f9190612a67565b604051602081830303815290604052805190602001201690508091505090565b6000808360010160008481526020019081526020016000205490506000811461253757600060018261246191906134d8565b905060006001866000018054905061247991906134d8565b90508181146124e857600086600001828154811061249a5761249961335c565b5b90600052602060002001549050808760000184815481106124be576124bd61335c565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b856000018054806124fc576124fb6139f4565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061253d565b60009150505b92915050565b606061254e84611bcf565b61258d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161258490613a95565b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516125b59190613af1565b600060405180830381855af49150503d80600081146125f0576040519150601f19603f3d011682016040523d82523d6000602084013e6125f5565b606091505b509150915061260582828661268e565b925050509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b600082600001828154811061264b5761264a61335c565b5b9060005260206000200154905092915050565b6000807f4bc804ba64359c0e35e5ed5d90ee596ecaa49a3a930ddcb1470ea0dd625da90060001b90508091505090565b6060831561269e578290506126ee565b6000835111156126b15782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126e59190613017565b60405180910390fd5b9392505050565b8280546127019061353b565b90600052602060002090601f016020900481019282612723576000855561276a565b82601f1061273c57805160ff191683800117855561276a565b8280016001018555821561276a579182015b8281111561276957825182559160200191906001019061274e565b5b509050612777919061277b565b5090565b5b8082111561279457600081600090555060010161277c565b5090565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006127ef826127c4565b9050919050565b6127ff816127e4565b82525050565b600061281183836127f6565b60208301905092915050565b6000602082019050919050565b600061283582612798565b61283f81856127a3565b935061284a836127b4565b8060005b8381101561287b5781516128628882612805565b975061286d8361281d565b92505060018101905061284e565b5085935050505092915050565b600060208201905081810360008301526128a2818461282a565b905092915050565b6000604051905090565b600080fd5b600080fd5b6128c7816127e4565b81146128d257600080fd5b50565b6000813590506128e4816128be565b92915050565b6000819050919050565b6128fd816128ea565b811461290857600080fd5b50565b60008135905061291a816128f4565b92915050565b60008060408385031215612937576129366128b4565b5b6000612945858286016128d5565b92505060206129568582860161290b565b9150509250929050565b600060208284031215612976576129756128b4565b5b6000612984848285016128d5565b91505092915050565b612996816127e4565b82525050565b60006020820190506129b1600083018461298d565b92915050565b6000602082840312156129cd576129cc6128b4565b5b60006129db8482850161290b565b91505092915050565b6129ed816128ea565b82525050565b6000602082019050612a0860008301846129e4565b92915050565b60008060408385031215612a2557612a246128b4565b5b6000612a338582860161290b565b9250506020612a44858286016128d5565b9150509250929050565b6000819050919050565b612a6181612a4e565b82525050565b6000602082019050612a7c6000830184612a58565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112612aa757612aa6612a82565b5b8235905067ffffffffffffffff811115612ac457612ac3612a87565b5b602083019150836001820283011115612ae057612adf612a8c565b5b9250929050565b600080600060408486031215612b0057612aff6128b4565b5b6000612b0e868287016128d5565b935050602084013567ffffffffffffffff811115612b2f57612b2e6128b9565b5b612b3b86828701612a91565b92509250509250925092565b612b5081612a4e565b8114612b5b57600080fd5b50565b600081359050612b6d81612b47565b92915050565b60008060408385031215612b8a57612b896128b4565b5b6000612b988582860161290b565b9250506020612ba985828601612b5e565b9150509250929050565b60008115159050919050565b612bc881612bb3565b82525050565b6000602082019050612be36000830184612bbf565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612c3782612bee565b810181811067ffffffffffffffff82111715612c5657612c55612bff565b5b80604052505050565b6000612c696128aa565b9050612c758282612c2e565b919050565b600067ffffffffffffffff821115612c9557612c94612bff565b5b612c9e82612bee565b9050602081019050919050565b82818337600083830152505050565b6000612ccd612cc884612c7a565b612c5f565b905082815260208101848484011115612ce957612ce8612be9565b5b612cf4848285612cab565b509392505050565b600082601f830112612d1157612d10612a82565b5b8135612d21848260208601612cba565b91505092915050565b600060208284031215612d4057612d3f6128b4565b5b600082013567ffffffffffffffff811115612d5e57612d5d6128b9565b5b612d6a84828501612cfc565b91505092915050565b60008083601f840112612d8957612d88612a82565b5b8235905067ffffffffffffffff811115612da657612da5612a87565b5b602083019150836020820283011115612dc257612dc1612a8c565b5b9250929050565b60008060208385031215612de057612ddf6128b4565b5b600083013567ffffffffffffffff811115612dfe57612dfd6128b9565b5b612e0a85828601612d73565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612e7c578082015181840152602081019050612e61565b83811115612e8b576000848401525b50505050565b6000612e9c82612e42565b612ea68185612e4d565b9350612eb6818560208601612e5e565b612ebf81612bee565b840191505092915050565b6000612ed68383612e91565b905092915050565b6000602082019050919050565b6000612ef682612e16565b612f008185612e21565b935083602082028501612f1285612e32565b8060005b85811015612f4e5784840389528151612f2f8582612eca565b9450612f3a83612ede565b925060208a01995050600181019050612f16565b50829750879550505050505092915050565b60006020820190508181036000830152612f7a8184612eeb565b905092915050565b60008060408385031215612f9957612f986128b4565b5b6000612fa785828601612b5e565b9250506020612fb885828601612b5e565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000612fe982612fc2565b612ff38185612fcd565b9350613003818560208601612e5e565b61300c81612bee565b840191505092915050565b600060208201905081810360008301526130318184612fde565b905092915050565b600080604083850312156130505761304f6128b4565b5b600061305e858286016128d5565b925050602083013567ffffffffffffffff81111561307f5761307e6128b9565b5b61308b85828601612cfc565b9150509250929050565b7f4163636f756e74466163746f72793a206e6f7420616e206163636f756e742e00600082015250565b60006130cb601f83612fcd565b91506130d682613095565b602082019050919050565b600060208201905081810360008301526130fa816130be565b9050919050565b7f43616e206f6e6c79206772616e7420746f206e6f6e20686f6c64657273000000600082015250565b6000613137601d83612fcd565b915061314282613101565b602082019050919050565b600060208201905081810360008301526131668161312a565b9050919050565b7f43616e206f6e6c792072656e6f756e636520666f722073656c66000000000000600082015250565b60006131a3601a83612fcd565b91506131ae8261316d565b602082019050919050565b600060208201905081810360008301526131d281613196565b9050919050565b7f4163636f756e74466163746f72793a206163636f756e7420616c72656164792060008201527f7265676973746572656400000000000000000000000000000000000000000000602082015250565b6000613235602a83612fcd565b9150613240826131d9565b604082019050919050565b6000602082019050818103600083015261326481613228565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006132a582612a4e565b91506132b083612a4e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156132e5576132e461326b565b5b828201905092915050565b7f4e6f7420617574686f72697a6564000000000000000000000000000000000000600082015250565b6000613326600e83612fcd565b9150613331826132f0565b602082019050919050565b6000602082019050818103600083015261335581613319565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126133b7576133b661338b565b5b80840192508235915067ffffffffffffffff8211156133d9576133d8613390565b5b6020830192506001820236038313156133f5576133f4613395565b5b509250929050565b600061340882612a4e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561343b5761343a61326b565b5b600182019050919050565b7f426173654163636f756e74466163746f72793a20696e76616c696420696e646960008201527f6365730000000000000000000000000000000000000000000000000000000000602082015250565b60006134a2602383612fcd565b91506134ad82613446565b604082019050919050565b600060208201905081810360008301526134d181613495565b9050919050565b60006134e382612a4e565b91506134ee83612a4e565b9250828210156135015761350061326b565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061355357607f821691505b602082108114156135675761356661350c565b5b50919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006135c9602e83612fcd565b91506135d48261356d565b604082019050919050565b600060208201905081810360008301526135f8816135bc565b9050919050565b6000819050919050565b600060ff82169050919050565b6000819050919050565b600061363b613636613631846135ff565b613616565b613609565b9050919050565b61364b81613620565b82525050565b60006020820190506136666000830184613642565b92915050565b600081905092915050565b7f5065726d697373696f6e733a206163636f756e74200000000000000000000000600082015250565b60006136ad60158361366c565b91506136b882613677565b601582019050919050565b60006136ce82612fc2565b6136d8818561366c565b93506136e8818560208601612e5e565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b600061372a60118361366c565b9150613735826136f4565b601182019050919050565b600061374b826136a0565b915061375782856136c3565b91506137628261371d565b915061376e82846136c3565b91508190509392505050565b600082825260208201905092915050565b600061379682612e42565b6137a0818561377a565b93506137b0818560208601612e5e565b6137b981612bee565b840191505092915050565b60006040820190506137d9600083018561298d565b81810360208301526137eb818461378b565b90509392505050565b6000604082019050818103600083015261380e8185612fde565b905081810360208301526138228184612fde565b90509392505050565b7f455243313136373a2063726561746532206661696c6564000000000000000000600082015250565b6000613861601783612fcd565b915061386c8261382b565b602082019050919050565b6000602082019050818103600083015261389081613854565b9050919050565b60006138a3838561377a565b93506138b0838584612cab565b6138b983612bee565b840190509392505050565b60006060820190506138d9600083018761298d565b6138e6602083018661298d565b81810360408301526138f9818486613897565b905095945050505050565b600061390f82612a4e565b915061391a83612a4e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156139535761395261326b565b5b828202905092915050565b600061396982612a4e565b9150600082141561397d5761397c61326b565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006139be602083612fcd565b91506139c982613988565b602082019050919050565b600060208201905081810360008301526139ed816139b1565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60008201527f6e74726163740000000000000000000000000000000000000000000000000000602082015250565b6000613a7f602683612fcd565b9150613a8a82613a23565b604082019050919050565b60006020820190508181036000830152613aae81613a72565b9050919050565b600081905092915050565b6000613acb82612e42565b613ad58185613ab5565b9350613ae5818560208601612e5e565b80840191505092915050565b6000613afd8284613ac0565b91508190509291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c0ef9945b017bc21a75c7486c027607288c2e1f8c96abf80075e371b5012e59164736f6c634300080c0033"; +bytes constant THIRDWEB_ACCOUNT_IMPL_BYTECODE = hex"6080604052600436106101bb5760003560e01c8063a9082d84116100ec578063cf7a1d771161008a578063e8a3d48511610064578063e8a3d48514610667578063e9523c9714610692578063f15d424e146106bd578063f23a6e61146106fa576101c2565b8063cf7a1d77146105e8578063d087d28814610611578063d42f2f351461063c576101c2565b8063b61d27f6116100c6578063b61d27f61461052e578063b76464d514610557578063bc197c8114610580578063c45a0155146105bd576101c2565b8063a9082d8414610488578063ac9650d8146104c6578063b0d691fe14610503576101c2565b806347e1da2a116101595780635892e236116101335780635892e236146103ce5780637dff5a79146103f75780638b52d72314610434578063938e3d7b1461045f576101c2565b806347e1da2a146103725780634a58db191461039b5780634d44560d146103a5576101c2565b80631626ba7e116101955780631626ba7e1461027e5780631dd756c5146102bb57806324d7806c146102f85780633a871cdd14610335576101c2565b806301ffc9a7146101c75780630a1028c414610204578063150b7a0214610241576101c2565b366101c257005b600080fd5b3480156101d357600080fd5b506101ee60048036038101906101e9919061415d565b610737565b6040516101fb91906141a5565b60405180910390f35b34801561021057600080fd5b5061022b60048036038101906102269190614306565b610819565b6040516102389190614368565b60405180910390f35b34801561024d57600080fd5b5061026860048036038101906102639190614417565b6108a6565b60405161027591906144a9565b60405180910390f35b34801561028a57600080fd5b506102a560048036038101906102a091906144f0565b6108ba565b6040516102b291906144a9565b60405180910390f35b3480156102c757600080fd5b506102e260048036038101906102dd9190614571565b610a42565b6040516102ef91906141a5565b60405180910390f35b34801561030457600080fd5b5061031f600480360381019061031a91906145cd565b610ec5565b60405161032c91906141a5565b60405180910390f35b34801561034157600080fd5b5061035c600480360381019061035791906145fa565b610f24565b6040516103699190614678565b60405180910390f35b34801561037e57600080fd5b506103996004803603810190610394919061479f565b610f57565b005b6103a361111a565b005b3480156103b157600080fd5b506103cc60048036038101906103c79190614891565b61118f565b005b3480156103da57600080fd5b506103f560048036038101906103f09190614947565b61120f565b005b34801561040357600080fd5b5061041e600480360381019061041991906145cd565b611763565b60405161042b91906141a5565b60405180910390f35b34801561044057600080fd5b506104496118f7565b6040516104569190614bf3565b60405180910390f35b34801561046b57600080fd5b5061048660048036038101906104819190614cb6565b611c8b565b005b34801561049457600080fd5b506104af60048036038101906104aa9190614947565b611cde565b6040516104bd929190614d0e565b60405180910390f35b3480156104d257600080fd5b506104ed60048036038101906104e89190614d37565b611d41565b6040516104fa9190614ece565b60405180910390f35b34801561050f57600080fd5b50610518611e4d565b6040516105259190614f4f565b60405180910390f35b34801561053a57600080fd5b5061055560048036038101906105509190614f6a565b611ee3565b005b34801561056357600080fd5b5061057e6004803603810190610579919061501c565b611fc6565b005b34801561058c57600080fd5b506105a760048036038101906105a2919061510c565b61201b565b6040516105b491906144a9565b60405180910390f35b3480156105c957600080fd5b506105d2612030565b6040516105df91906151db565b60405180910390f35b3480156105f457600080fd5b5061060f600480360381019061060a91906151f6565b612063565b005b34801561061d57600080fd5b50610626612280565b6040516106339190614678565b60405180910390f35b34801561064857600080fd5b5061065161230b565b60405161065e9190614bf3565b60405180910390f35b34801561067357600080fd5b5061067c612595565b60405161068991906152bf565b60405180910390f35b34801561069e57600080fd5b506106a7612630565b6040516106b49190615350565b60405180910390f35b3480156106c957600080fd5b506106e460048036038101906106df91906145cd565b61264a565b6040516106f191906153e8565b60405180910390f35b34801561070657600080fd5b50610721600480360381019061071c919061540a565b61280b565b60405161072e91906144a9565b60405180910390f35b60007f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061080257507f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610812575061081182612850565b5b9050919050565b6000807f82cac545155fcbf147f2a9013809613677ac7d65498556e6d19ce43bcbf6c28483805190602001206040516020016108569291906154a1565b6040516020818303038152906040528051906020012090506108766128ca565b81604051602001610888929190615542565b60405160208183030381529060405280519060200120915050919050565b600063150b7a0260e01b9050949350505050565b6000806108e5846040516020016108d19190614368565b604051602081830303815290604052610819565b905060006108fc84836129e490919063ffffffff16565b905061090781610ec5565b1561091d57631626ba7e60e01b92505050610a3c565b6000339050600061092c612a0b565b60060160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506109818282612a1a90919063ffffffff16565b806109df5750600161099282612a4a565b1480156109de5750600073ffffffffffffffffffffffffffffffffffffffff166109c6600083612a5f90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff16145b5b610a1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a15906155eb565b60405180910390fd5b610a2783611763565b15610a3757631626ba7e60e01b94505b505050505b92915050565b6000610a4c612a0b565b60040160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610aa85760019050610ebf565b6000610ab2612a0b565b60050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806060016040529081600082015481526020016001820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff168152505090506000610ba7612a0b565b60060160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090504282602001516fffffffffffffffffffffffffffffffff161180610c23575081604001516fffffffffffffffffffffffffffffffff164210155b80610c3657506000610c3482612a4a565b145b15610c4657600092505050610ebf565b6000610c60858060600190610c5b919061561a565b612a79565b905060006001610c6f84612a4a565b148015610cbb5750600073ffffffffffffffffffffffffffffffffffffffff16610ca3600085612a5f90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff16145b905063b61d27f660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610d7757600080610d25888060600190610d20919061561a565b612ae9565b9150915082610d5557610d418286612a1a90919063ffffffff16565b610d545760009650505050505050610ebf565b5b8086600001511015610d705760009650505050505050610ebf565b5050610eb6565b6347e1da2a60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610ea857600080610ddf888060600190610dda919061561a565b612b80565b509150915082610e4b5760005b8251811015610e4957610e22838281518110610e0b57610e0a61567d565b5b602002602001015187612a1a90919063ffffffff16565b610e36576000975050505050505050610ebf565b8080610e41906156db565b915050610dec565b505b60005b8251811015610ea057818181518110610e6a57610e6961567d565b5b602002602001015187600001511015610e8d576000975050505050505050610ebf565b8080610e98906156db565b915050610e4e565b505050610eb5565b6000945050505050610ebf565b5b60019450505050505b92915050565b6000610ecf612a0b565b60040160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000610f2e612bff565b610f388484612c76565b9050610f478460200135612e66565b610f5082612e69565b9392505050565b610f5f611e4d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610f9d5750610f9c33610ec5565b5b610fdc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd390615796565b60405180910390fd5b610fe4612f05565b8181905086869050148015610ffe57508383905086869050145b61103d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103490615802565b60405180910390fd5b60005b86869050811015611111576110fd8787838181106110615761106061567d565b5b905060200201602081019061107691906145cd565b8686848181106110895761108861567d565b5b905060200201358585858181106110a3576110a261567d565b5b90506020028101906110b5919061561a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061302d565b508080611109906156db565b915050611040565b50505050505050565b611122611e4d565b73ffffffffffffffffffffffffffffffffffffffff1663b760faf934306040518363ffffffff1660e01b815260040161115b91906151db565b6000604051808303818588803b15801561117457600080fd5b505af1158015611188573d6000803e3d6000fd5b5050505050565b6111976130b7565b61119f611e4d565b73ffffffffffffffffffffffffffffffffffffffff1663205c287883836040518363ffffffff1660e01b81526004016111d9929190615831565b600060405180830381600087803b1580156111f357600080fd5b505af1158015611207573d6000803e3d6000fd5b505050505050565b600083600001602081019061122491906145cd565b9050428460c001602081019061123a9190615886565b6fffffffffffffffffffffffffffffffff161115801561127d57508360e00160208101906112689190615886565b6fffffffffffffffffffffffffffffffff1642105b6112bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b3906158ff565b60405180910390fd5b6000806112ca868686611cde565b915091508161130e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113059061596b565b60405180910390fd5b6001611318612a0b565b6007016000886101000135815260200190815260200160002060006101000a81548160ff021916908315150217905550600086602001602081019061135d91906159c4565b60ff161115611396576000600187602001602081019061137d91906159c4565b60ff1614905061138d8482613101565b5050505061175e565b61139f83610ec5565b156113df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d690615a3d565b60405180910390fd5b6113fc836113eb612a0b565b60020161323990919063ffffffff16565b506040518060600160405280876060013581526020018760800160208101906114259190615886565b6fffffffffffffffffffffffffffffffff1681526020018760a001602081019061144f9190615886565b6fffffffffffffffffffffffffffffffff1681525061146c612a0b565b60050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000820151816000015560208201518160010160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060408201518160010160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055509050506000611589611544612a0b565b60060160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020613269565b905060008151905060005b81811015611625576116108382815181106115b2576115b161567d565b5b60200260200101516115c2612a0b565b60060160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061328a90919063ffffffff16565b5060018161161e9190615a5d565b9050611594565b508780604001906116369190615ab3565b9050905060005b818110156116e9576116d48980604001906116589190615ab3565b838181106116695761166861567d565b5b905060200201602081019061167e91906145cd565b611686612a0b565b60060160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061323990919063ffffffff16565b506001816116e29190615a5d565b905061163d565b506116f3886132ba565b8473ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ff21d10c26e35863a8df291aca54181ee8c4a3bc8e00246c3f7a5a14b69d826a78a6040516117509190615d9c565b60405180910390a350505050505b505050565b60008061176e612a0b565b60050160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806060016040529081600082015481526020016001820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff168152505090504281602001516fffffffffffffffffffffffffffffffff1611158015611894575080604001516fffffffffffffffffffffffffffffffff1642105b80156118ef575060006118ed6118a8612a0b565b60060160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612a4a565b115b915050919050565b6060600061190e611906612a0b565b600201613269565b90506000815190506000805b828110156119c1576119458482815181106119385761193761567d565b5b6020026020010151611763565b1561195d578180611955906156db565b9250506119ad565b60008482815181106119725761197161567d565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b6001816119ba9190615a5d565b905061191a565b508067ffffffffffffffff8111156119dc576119db6141db565b5b604051908082528060200260200182016040528015611a1557816020015b611a02613fe5565b8152602001906001900390816119fa5790505b5093506000805b83811015611c8357600073ffffffffffffffffffffffffffffffffffffffff16858281518110611a4f57611a4e61567d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614611c6f576000858281518110611a8757611a8661567d565b5b602002602001015190506000611a9b612a0b565b60050160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806060016040529081600082015481526020016001820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff168152505090506040518060a001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001611bfd611bb8612a0b565b60060160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020613269565b81526020018260000151815260200182602001516fffffffffffffffffffffffffffffffff16815260200182604001516fffffffffffffffffffffffffffffffff16815250888580611c4e906156db565b965081518110611c6157611c6061567d565b5b602002602001018190525050505b600181611c7c9190615a5d565b9050611a1c565b505050505090565b611c93613375565b611cd2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc990615e0a565b60405180910390fd5b611cdb816133bb565b50565b600080611cf4611ced866134b0565b85856135b6565b9050611cfe612a0b565b6007016000866101000135815260200190815260200160002060009054906101000a900460ff16158015611d375750611d3681610ec5565b5b9150935093915050565b60608282905067ffffffffffffffff811115611d6057611d5f6141db565b5b604051908082528060200260200182016040528015611d9357816020015b6060815260200190600190039081611d7e5790505b50905060005b83839050811015611e4657611e1530858584818110611dbb57611dba61567d565b5b9050602002810190611dcd919061561a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050613627565b828281518110611e2857611e2761567d565b5b60200260200101819052508080611e3e906156db565b915050611d99565b5092915050565b600080611e58613654565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611ebb5780915050611ee0565b7f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d27899150505b90565b611eeb611e4d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480611f295750611f2833610ec5565b5b611f68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5f90615796565b60405180910390fd5b611f70612f05565b611fbf848484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061302d565b5050505050565b611fce6130b7565b80611fd7613654565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600063bc197c8160e01b905095945050505050565b600061203a613654565b60010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600061206d613684565b60000160009054906101000a900460ff169050600061208a613684565b60000160019054906101000a900460ff1690506000811590508080156120b3575060018360ff16105b806120d357506120c230613693565b1580156120d2575060018360ff16145b5b612112576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161210990615e9c565b60405180910390fd5b600161211c613684565b60000160006101000a81548160ff021916908360ff1602179055508015612162576001612147613684565b60000160016101000a81548160ff0219169083151502179055505b6121b08786868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506136b6565b6121b8613654565b60020181905550856121c8613654565b60010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612214876001613101565b8015612277576000612224613684565b60000160016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498600160405161226e9190615ef7565b60405180910390a15b50505050505050565b600061228a611e4d565b73ffffffffffffffffffffffffffffffffffffffff166335567e1a3060006040518363ffffffff1660e01b81526004016122c5929190615f71565b602060405180830381865afa1580156122e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123069190615faf565b905090565b6060600061232261231a612a0b565b600201613269565b90506000815190508067ffffffffffffffff811115612344576123436141db565b5b60405190808252806020026020018201604052801561237d57816020015b61236a613fe5565b8152602001906001900390816123625790505b50925060005b8181101561258f5760008382815181106123a05761239f61567d565b5b6020026020010151905060006123b4612a0b565b60050160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806060016040529081600082015481526020016001820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff168152505090506040518060a001604052808373ffffffffffffffffffffffffffffffffffffffff1681526020016125166124d1612a0b565b60060160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020613269565b81526020018260000151815260200182602001516fffffffffffffffffffffffffffffffff16815260200182604001516fffffffffffffffffffffffffffffffff1681525086848151811061256e5761256d61567d565b5b602002602001018190525050506001816125889190615a5d565b9050612383565b50505090565b606061259f6136e9565b60000180546125ad9061600b565b80601f01602080910402602001604051908101604052809291908181526020018280546125d99061600b565b80156126265780601f106125fb57610100808354040283529160200191612626565b820191906000526020600020905b81548152906001019060200180831161260957829003601f168201915b5050505050905090565b606061264561263d612a0b565b600001613269565b905090565b612652613fe5565b600061265c612a0b565b60050160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806060016040529081600082015481526020016001820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff168152505090506040518060a001604052808473ffffffffffffffffffffffffffffffffffffffff1681526020016127be612779612a0b565b60060160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020613269565b81526020018260000151815260200182602001516fffffffffffffffffffffffffffffffff16815260200182604001516fffffffffffffffffffffffffffffffff16815250915050919050565b600063f23a6e6160e01b905095945050505050565b6000807f322cf19c484104d3b1a9c2982ebae869ede3fa5f6c4703ca41b9a48c76ee030060001b90508091505090565b60007f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806128c357506128c2826136f8565b5b9050919050565b60007f000000000000000000000000ffd4505b3452dc22f8473616d50503ba9e1710ac73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614801561294657507f0000000000000000000000000000000000000000000000000000000000007a6946145b15612973577fbcdadf6444930a967ffda04923d78c49b3dd65df3ed39abb04a1e3eb1190553790506129e1565b6129de7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7ff0729608244859f656d32ae4cbc6b0367695d68d8e941a28f5e2d33c6d5182dd7fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6613762565b90505b90565b60008060006129f3858561379c565b91509150612a00816137ee565b819250505092915050565b6000612a1561395c565b905090565b6000612a42836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61398c565b905092915050565b6000612a58826000016139af565b9050919050565b6000612a6e83600001836139c0565b60001c905092915050565b60006004838390501015612ac2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ab990616089565b60405180910390fd5b8282600090600492612ad6939291906160b3565b90612ae19190616106565b905092915050565b6000806044848490501015612b33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b2a90616089565b60405180910390fd5b8383600490602492612b47939291906160b3565b810190612b549190616165565b91508383602490604492612b6a939291906160b3565b810190612b779190616192565b90509250929050565b60608060606064858590501015612bcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bc390616089565b60405180910390fd5b84846004908092612bdf939291906160b3565b810190612bec9190616363565b8093508194508295505050509250925092565b612c07611e4d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612c74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c6b90616456565b60405180910390fd5b565b600080612c82836139eb565b90506000612cec85806101400190612c9a919061561a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050836129e490919063ffffffff16565b9050612cf88186610a42565b612d0757600192505050612e60565b6000612d11612a0b565b60050160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806060016040529081600082015481526020016001820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815250509050600081602001519050600082604001519050612e586040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020018465ffffffffffff1681526020018365ffffffffffff16815250613a21565b955050505050505b92915050565b50565b60008114612f025760003373ffffffffffffffffffffffffffffffffffffffff16827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90604051612eb9906164a7565b600060405180830381858888f193505050503d8060008114612ef7576040519150601f19603f3d011682016040523d82523d6000602084013e612efc565b606091505b50509050505b50565b6000612f0f613654565b60010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663c3c5a547306040518263ffffffff1660e01b8152600401612f6e91906151db565b602060405180830381865afa158015612f8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612faf91906164e8565b61302a578073ffffffffffffffffffffffffffffffffffffffff166383a03f8c612fd7613654565b600201546040518263ffffffff1660e01b8152600401612ff79190614368565b600060405180830381600087803b15801561301157600080fd5b505af1158015613025573d6000803e3d6000fd5b505050505b50565b606060008473ffffffffffffffffffffffffffffffffffffffff1684846040516130579190616546565b60006040518083038185875af1925050503d8060008114613094576040519150601f19603f3d011682016040523d82523d6000602084013e613099565b606091505b508093508192505050806130af57815160208301fd5b509392505050565b6130c033610ec5565b6130ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130f6906165a9565b60405180910390fd5b565b61310b8282613a69565b6000613115612030565b905060008173ffffffffffffffffffffffffffffffffffffffff163b11156132345781156131ba578073ffffffffffffffffffffffffffffffffffffffff16630b61e12b84613162613654565b600201546040518363ffffffff1660e01b81526004016131839291906165c9565b600060405180830381600087803b15801561319d57600080fd5b505af11580156131b1573d6000803e3d6000fd5b50505050613233565b8073ffffffffffffffffffffffffffffffffffffffff16639387a380846131df613654565b600201546040518363ffffffff1660e01b81526004016132009291906165c9565b600060405180830381600087803b15801561321a57600080fd5b505af115801561322e573d6000803e3d6000fd5b505050505b5b505050565b6000613261836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613b63565b905092915050565b6060600061327983600001613bd3565b905060608190508092505050919050565b60006132b2836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613c2f565b905092915050565b60006132c4612030565b905060008173ffffffffffffffffffffffffffffffffffffffff163b1115613371578073ffffffffffffffffffffffffffffffffffffffff16630b61e12b83600001602081019061331591906145cd565b61331d613654565b600201546040518363ffffffff1660e01b815260040161333e9291906165c9565b600060405180830381600087803b15801561335857600080fd5b505af115801561336c573d6000803e3d6000fd5b505050505b5050565b600061338033610ec5565b806133b657503073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b905090565b60006133c56136e9565b60000180546133d39061600b565b80601f01602080910402602001604051908101604052809291908181526020018280546133ff9061600b565b801561344c5780601f106134215761010080835404028352916020019161344c565b820191906000526020600020905b81548152906001019060200180831161342f57829003601f168201915b505050505090508161345c6136e9565b600001908051906020019061347292919061404e565b507fc9c7c3fe08b88b4df9d4d47ef47d2c43d55c025a0ba88ca442580ed9e7348a1681836040516134a49291906165f2565b60405180910390a15050565b60607f3fd4a1a1a267c84185e3b7eecd57c68783c0581d538b9d6e5f23e4670497c1e98260000160208101906134e691906145cd565b8360200160208101906134f991906159c4565b8480604001906135099190615ab3565b60405160200161351a9291906166b8565b6040516020818303038152906040528051906020012085606001358660800160208101906135489190615886565b8760a001602081019061355b9190615886565b8860c001602081019061356e9190615886565b8960e00160208101906135819190615886565b8a61010001356040516020016135a09a999897969594939291906166ef565b6040516020818303038152906040529050919050565b600061361e83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506136108680519060200120613d43565b6129e490919063ffffffff16565b90509392505050565b606061364c8383604051806060016040528060278152602001616b2c60279139613d5d565b905092915050565b6000807f036f52c1827dab135f7fd44ca0bddde297e2f659c710e0ec53e975f22b54830060001b90508091505090565b600061368e612820565b905090565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600082826040516020016136cb9291906167d5565b60405160208183030381529060405280519060200120905092915050565b60006136f3613e2a565b905090565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6000838383463060405160200161377d959493929190616805565b6040516020818303038152906040528051906020012090509392505050565b6000806041835114156137de5760008060006020860151925060408601519150606086015160001a90506137d287828585613e5a565b945094505050506137e7565b60006002915091505b9250929050565b6000600481111561380257613801616858565b5b81600481111561381557613814616858565b5b141561382057613959565b6001600481111561383457613833616858565b5b81600481111561384757613846616858565b5b1415613888576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161387f906168d3565b60405180910390fd5b6002600481111561389c5761389b616858565b5b8160048111156138af576138ae616858565b5b14156138f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138e79061693f565b60405180910390fd5b6003600481111561390457613903616858565b5b81600481111561391757613916616858565b5b1415613958576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161394f906169d1565b60405180910390fd5b5b50565b6000807f3181e78fc1b109bc611fd2406150bf06e33faa75f71cba12c3e1fd670f2def0060001b90508091505090565b600080836001016000848152602001908152602001600020541415905092915050565b600081600001805490509050919050565b60008260000182815481106139d8576139d761567d565b5b9060005260206000200154905092915050565b60007f19457468657265756d205369676e6564204d6573736167653a0a33320000000060005281601c52603c6000209050919050565b600060d0826020015165ffffffffffff16901b60a0836040015165ffffffffffff16901b836000015173ffffffffffffffffffffffffffffffffffffffff1617179050919050565b80613a72612a0b565b60040160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508015613af257613aec82613adb612a0b565b60000161323990919063ffffffff16565b50613b11565b613b0f82613afe612a0b565b60000161328a90919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f235bc17e7930760029e9f4d860a2a8089976de5b381cf8380fc11c1d88a1113382604051613b5791906141a5565b60405180910390a25050565b6000613b6f838361398c565b613bc8578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613bcd565b600090505b92915050565b606081600001805480602002602001604051908101604052809291908181526020018280548015613c2357602002820191906000526020600020905b815481526020019060010190808311613c0f575b50505050509050919050565b60008083600101600084815260200190815260200160002054905060008114613d37576000600182613c6191906169f1565b9050600060018660000180549050613c7991906169f1565b9050818114613ce8576000866000018281548110613c9a57613c9961567d565b5b9060005260206000200154905080876000018481548110613cbe57613cbd61567d565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480613cfc57613cfb616a25565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613d3d565b60009150505b92915050565b6000613d56613d506128ca565b83613f3d565b9050919050565b6060613d6884613693565b613da7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d9e90616ac6565b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff1685604051613dcf9190616546565b600060405180830381855af49150503d8060008114613e0a576040519150601f19603f3d011682016040523d82523d6000602084013e613e0f565b606091505b5091509150613e1f828286613f7e565b925050509392505050565b6000807f4bc804ba64359c0e35e5ed5d90ee596ecaa49a3a930ddcb1470ea0dd625da90060001b90508091505090565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115613e95576000600391509150613f34565b600060018787878760405160008152602001604052604051613eba9493929190616ae6565b6020604051602081039080840390855afa158015613edc573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613f2b57600060019250925050613f34565b80600092509250505b94509492505050565b60006040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b60608315613f8e57829050613fde565b600083511115613fa15782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613fd591906152bf565b60405180910390fd5b9392505050565b6040518060a00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081526020016000815260200160006fffffffffffffffffffffffffffffffff16815260200160006fffffffffffffffffffffffffffffffff1681525090565b82805461405a9061600b565b90600052602060002090601f01602090048101928261407c57600085556140c3565b82601f1061409557805160ff19168380011785556140c3565b828001600101855582156140c3579182015b828111156140c25782518255916020019190600101906140a7565b5b5090506140d091906140d4565b5090565b5b808211156140ed5760008160009055506001016140d5565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61413a81614105565b811461414557600080fd5b50565b60008135905061415781614131565b92915050565b600060208284031215614173576141726140fb565b5b600061418184828501614148565b91505092915050565b60008115159050919050565b61419f8161418a565b82525050565b60006020820190506141ba6000830184614196565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b614213826141ca565b810181811067ffffffffffffffff82111715614232576142316141db565b5b80604052505050565b60006142456140f1565b9050614251828261420a565b919050565b600067ffffffffffffffff821115614271576142706141db565b5b61427a826141ca565b9050602081019050919050565b82818337600083830152505050565b60006142a96142a484614256565b61423b565b9050828152602081018484840111156142c5576142c46141c5565b5b6142d0848285614287565b509392505050565b600082601f8301126142ed576142ec6141c0565b5b81356142fd848260208601614296565b91505092915050565b60006020828403121561431c5761431b6140fb565b5b600082013567ffffffffffffffff81111561433a57614339614100565b5b614346848285016142d8565b91505092915050565b6000819050919050565b6143628161434f565b82525050565b600060208201905061437d6000830184614359565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006143ae82614383565b9050919050565b6143be816143a3565b81146143c957600080fd5b50565b6000813590506143db816143b5565b92915050565b6000819050919050565b6143f4816143e1565b81146143ff57600080fd5b50565b600081359050614411816143eb565b92915050565b60008060008060808587031215614431576144306140fb565b5b600061443f878288016143cc565b9450506020614450878288016143cc565b935050604061446187828801614402565b925050606085013567ffffffffffffffff81111561448257614481614100565b5b61448e878288016142d8565b91505092959194509250565b6144a381614105565b82525050565b60006020820190506144be600083018461449a565b92915050565b6144cd8161434f565b81146144d857600080fd5b50565b6000813590506144ea816144c4565b92915050565b60008060408385031215614507576145066140fb565b5b6000614515858286016144db565b925050602083013567ffffffffffffffff81111561453657614535614100565b5b614542858286016142d8565b9150509250929050565b600080fd5b600061016082840312156145685761456761454c565b5b81905092915050565b60008060408385031215614588576145876140fb565b5b6000614596858286016143cc565b925050602083013567ffffffffffffffff8111156145b7576145b6614100565b5b6145c385828601614551565b9150509250929050565b6000602082840312156145e3576145e26140fb565b5b60006145f1848285016143cc565b91505092915050565b600080600060608486031215614613576146126140fb565b5b600084013567ffffffffffffffff81111561463157614630614100565b5b61463d86828701614551565b935050602061464e868287016144db565b925050604061465f86828701614402565b9150509250925092565b614672816143e1565b82525050565b600060208201905061468d6000830184614669565b92915050565b600080fd5b600080fd5b60008083601f8401126146b3576146b26141c0565b5b8235905067ffffffffffffffff8111156146d0576146cf614693565b5b6020830191508360208202830111156146ec576146eb614698565b5b9250929050565b60008083601f840112614709576147086141c0565b5b8235905067ffffffffffffffff81111561472657614725614693565b5b60208301915083602082028301111561474257614741614698565b5b9250929050565b60008083601f84011261475f5761475e6141c0565b5b8235905067ffffffffffffffff81111561477c5761477b614693565b5b60208301915083602082028301111561479857614797614698565b5b9250929050565b600080600080600080606087890312156147bc576147bb6140fb565b5b600087013567ffffffffffffffff8111156147da576147d9614100565b5b6147e689828a0161469d565b9650965050602087013567ffffffffffffffff81111561480957614808614100565b5b61481589828a016146f3565b9450945050604087013567ffffffffffffffff81111561483857614837614100565b5b61484489828a01614749565b92509250509295509295509295565b600061485e82614383565b9050919050565b61486e81614853565b811461487957600080fd5b50565b60008135905061488b81614865565b92915050565b600080604083850312156148a8576148a76140fb565b5b60006148b68582860161487c565b92505060206148c785828601614402565b9150509250929050565b600061012082840312156148e8576148e761454c565b5b81905092915050565b60008083601f840112614907576149066141c0565b5b8235905067ffffffffffffffff81111561492457614923614693565b5b6020830191508360018202830111156149405761493f614698565b5b9250929050565b6000806000604084860312156149605761495f6140fb565b5b600084013567ffffffffffffffff81111561497e5761497d614100565b5b61498a868287016148d1565b935050602084013567ffffffffffffffff8111156149ab576149aa614100565b5b6149b7868287016148f1565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6149f8816143a3565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000614a3683836149ef565b60208301905092915050565b6000602082019050919050565b6000614a5a826149fe565b614a648185614a09565b9350614a6f83614a1a565b8060005b83811015614aa0578151614a878882614a2a565b9750614a9283614a42565b925050600181019050614a73565b5085935050505092915050565b614ab6816143e1565b82525050565b60006fffffffffffffffffffffffffffffffff82169050919050565b614ae181614abc565b82525050565b600060a083016000830151614aff60008601826149ef565b5060208301518482036020860152614b178282614a4f565b9150506040830151614b2c6040860182614aad565b506060830151614b3f6060860182614ad8565b506080830151614b526080860182614ad8565b508091505092915050565b6000614b698383614ae7565b905092915050565b6000602082019050919050565b6000614b89826149c3565b614b9381856149ce565b935083602082028501614ba5856149df565b8060005b85811015614be15784840389528151614bc28582614b5d565b9450614bcd83614b71565b925060208a01995050600181019050614ba9565b50829750879550505050505092915050565b60006020820190508181036000830152614c0d8184614b7e565b905092915050565b600067ffffffffffffffff821115614c3057614c2f6141db565b5b614c39826141ca565b9050602081019050919050565b6000614c59614c5484614c15565b61423b565b905082815260208101848484011115614c7557614c746141c5565b5b614c80848285614287565b509392505050565b600082601f830112614c9d57614c9c6141c0565b5b8135614cad848260208601614c46565b91505092915050565b600060208284031215614ccc57614ccb6140fb565b5b600082013567ffffffffffffffff811115614cea57614ce9614100565b5b614cf684828501614c88565b91505092915050565b614d08816143a3565b82525050565b6000604082019050614d236000830185614196565b614d306020830184614cff565b9392505050565b60008060208385031215614d4e57614d4d6140fb565b5b600083013567ffffffffffffffff811115614d6c57614d6b614100565b5b614d7885828601614749565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015614dea578082015181840152602081019050614dcf565b83811115614df9576000848401525b50505050565b6000614e0a82614db0565b614e148185614dbb565b9350614e24818560208601614dcc565b614e2d816141ca565b840191505092915050565b6000614e448383614dff565b905092915050565b6000602082019050919050565b6000614e6482614d84565b614e6e8185614d8f565b935083602082028501614e8085614da0565b8060005b85811015614ebc5784840389528151614e9d8582614e38565b9450614ea883614e4c565b925060208a01995050600181019050614e84565b50829750879550505050505092915050565b60006020820190508181036000830152614ee88184614e59565b905092915050565b6000819050919050565b6000614f15614f10614f0b84614383565b614ef0565b614383565b9050919050565b6000614f2782614efa565b9050919050565b6000614f3982614f1c565b9050919050565b614f4981614f2e565b82525050565b6000602082019050614f646000830184614f40565b92915050565b60008060008060608587031215614f8457614f836140fb565b5b6000614f92878288016143cc565b9450506020614fa387828801614402565b935050604085013567ffffffffffffffff811115614fc457614fc3614100565b5b614fd0878288016148f1565b925092505092959194509250565b6000614fe9826143a3565b9050919050565b614ff981614fde565b811461500457600080fd5b50565b60008135905061501681614ff0565b92915050565b600060208284031215615032576150316140fb565b5b600061504084828501615007565b91505092915050565b600067ffffffffffffffff821115615064576150636141db565b5b602082029050602081019050919050565b600061508861508384615049565b61423b565b905080838252602082019050602084028301858111156150ab576150aa614698565b5b835b818110156150d457806150c08882614402565b8452602084019350506020810190506150ad565b5050509392505050565b600082601f8301126150f3576150f26141c0565b5b8135615103848260208601615075565b91505092915050565b600080600080600060a08688031215615128576151276140fb565b5b6000615136888289016143cc565b9550506020615147888289016143cc565b945050604086013567ffffffffffffffff81111561516857615167614100565b5b615174888289016150de565b935050606086013567ffffffffffffffff81111561519557615194614100565b5b6151a1888289016150de565b925050608086013567ffffffffffffffff8111156151c2576151c1614100565b5b6151ce888289016142d8565b9150509295509295909350565b60006020820190506151f06000830184614cff565b92915050565b600080600080606085870312156152105761520f6140fb565b5b600061521e878288016143cc565b945050602061522f878288016143cc565b935050604085013567ffffffffffffffff8111156152505761524f614100565b5b61525c878288016148f1565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b60006152918261526a565b61529b8185615275565b93506152ab818560208601614dcc565b6152b4816141ca565b840191505092915050565b600060208201905081810360008301526152d98184615286565b905092915050565b600082825260208201905092915050565b60006152fd826149fe565b61530781856152e1565b935061531283614a1a565b8060005b8381101561534357815161532a8882614a2a565b975061533583614a42565b925050600181019050615316565b5085935050505092915050565b6000602082019050818103600083015261536a81846152f2565b905092915050565b600060a08301600083015161538a60008601826149ef565b50602083015184820360208601526153a28282614a4f565b91505060408301516153b76040860182614aad565b5060608301516153ca6060860182614ad8565b5060808301516153dd6080860182614ad8565b508091505092915050565b600060208201905081810360008301526154028184615372565b905092915050565b600080600080600060a08688031215615426576154256140fb565b5b6000615434888289016143cc565b9550506020615445888289016143cc565b945050604061545688828901614402565b935050606061546788828901614402565b925050608086013567ffffffffffffffff81111561548857615487614100565b5b615494888289016142d8565b9150509295509295909350565b60006040820190506154b66000830185614359565b6154c36020830184614359565b9392505050565b600081905092915050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b600061550b6002836154ca565b9150615516826154d5565b600282019050919050565b6000819050919050565b61553c6155378261434f565b615521565b82525050565b600061554d826154fe565b9150615559828561552b565b602082019150615569828461552b565b6020820191508190509392505050565b7f4163636f756e743a2063616c6c6572206e6f7420617070726f7665642074617260008201527f6765742e00000000000000000000000000000000000000000000000000000000602082015250565b60006155d5602483615275565b91506155e082615579565b604082019050919050565b60006020820190508181036000830152615604816155c8565b9050919050565b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126156375761563661560b565b5b80840192508235915067ffffffffffffffff82111561565957615658615610565b5b60208301925060018202360383131561567557615674615615565b5b509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006156e6826143e1565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415615719576157186156ac565b5b600182019050919050565b7f4163636f756e743a206e6f742061646d696e206f7220456e747279506f696e7460008201527f2e00000000000000000000000000000000000000000000000000000000000000602082015250565b6000615780602183615275565b915061578b82615724565b604082019050919050565b600060208201905081810360008301526157af81615773565b9050919050565b7f4163636f756e743a2077726f6e67206172726179206c656e677468732e000000600082015250565b60006157ec601d83615275565b91506157f7826157b6565b602082019050919050565b6000602082019050818103600083015261581b816157df565b9050919050565b61582b81614853565b82525050565b60006040820190506158466000830185615822565b6158536020830184614669565b9392505050565b61586381614abc565b811461586e57600080fd5b50565b6000813590506158808161585a565b92915050565b60006020828403121561589c5761589b6140fb565b5b60006158aa84828501615871565b91505092915050565b7f21706572696f6400000000000000000000000000000000000000000000000000600082015250565b60006158e9600783615275565b91506158f4826158b3565b602082019050919050565b60006020820190508181036000830152615918816158dc565b9050919050565b7f2173696700000000000000000000000000000000000000000000000000000000600082015250565b6000615955600483615275565b91506159608261591f565b602082019050919050565b6000602082019050818103600083015261598481615948565b9050919050565b600060ff82169050919050565b6159a18161598b565b81146159ac57600080fd5b50565b6000813590506159be81615998565b92915050565b6000602082840312156159da576159d96140fb565b5b60006159e8848285016159af565b91505092915050565b7f61646d696e000000000000000000000000000000000000000000000000000000600082015250565b6000615a27600583615275565b9150615a32826159f1565b602082019050919050565b60006020820190508181036000830152615a5681615a1a565b9050919050565b6000615a68826143e1565b9150615a73836143e1565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115615aa857615aa76156ac565b5b828201905092915050565b60008083356001602003843603038112615ad057615acf61560b565b5b80840192508235915067ffffffffffffffff821115615af257615af1615610565b5b602083019250602082023603831315615b0e57615b0d615615565b5b509250929050565b6000615b2560208401846143cc565b905092915050565b6000615b3c60208401846159af565b905092915050565b615b4d8161598b565b82525050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112615b7f57615b7e615b5d565b5b83810192508235915060208301925067ffffffffffffffff821115615ba757615ba6615b53565b5b602082023603841315615bbd57615bbc615b58565b5b509250929050565b6000819050919050565b6000602082019050919050565b6000615be88385614a09565b9350615bf382615bc5565b8060005b85811015615c2c57615c098284615b16565b615c138882614a2a565b9750615c1e83615bcf565b925050600181019050615bf7565b5085925050509392505050565b6000615c486020840184614402565b905092915050565b6000615c5f6020840184615871565b905092915050565b6000615c7660208401846144db565b905092915050565b615c878161434f565b82525050565b60006101208301615ca16000840184615b16565b615cae60008601826149ef565b50615cbc6020840184615b2d565b615cc96020860182615b44565b50615cd76040840184615b62565b8583036040870152615cea838284615bdc565b92505050615cfb6060840184615c39565b615d086060860182614aad565b50615d166080840184615c50565b615d236080860182614ad8565b50615d3160a0840184615c50565b615d3e60a0860182614ad8565b50615d4c60c0840184615c50565b615d5960c0860182614ad8565b50615d6760e0840184615c50565b615d7460e0860182614ad8565b50615d83610100840184615c67565b615d91610100860182615c7e565b508091505092915050565b60006020820190508181036000830152615db68184615c8d565b905092915050565b7f4e6f7420617574686f72697a6564000000000000000000000000000000000000600082015250565b6000615df4600e83615275565b9150615dff82615dbe565b602082019050919050565b60006020820190508181036000830152615e2381615de7565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b6000615e86602e83615275565b9150615e9182615e2a565b604082019050919050565b60006020820190508181036000830152615eb581615e79565b9050919050565b6000819050919050565b6000615ee1615edc615ed784615ebc565b614ef0565b61598b565b9050919050565b615ef181615ec6565b82525050565b6000602082019050615f0c6000830184615ee8565b92915050565b6000819050919050565b600077ffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6000615f5b615f56615f5184615f12565b614ef0565b615f1c565b9050919050565b615f6b81615f40565b82525050565b6000604082019050615f866000830185614cff565b615f936020830184615f62565b9392505050565b600081519050615fa9816143eb565b92915050565b600060208284031215615fc557615fc46140fb565b5b6000615fd384828501615f9a565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061602357607f821691505b6020821081141561603757616036615fdc565b5b50919050565b7f2144617461000000000000000000000000000000000000000000000000000000600082015250565b6000616073600583615275565b915061607e8261603d565b602082019050919050565b600060208201905081810360008301526160a281616066565b9050919050565b600080fd5b600080fd5b600080858511156160c7576160c66160a9565b5b838611156160d8576160d76160ae565b5b6001850283019150848603905094509492505050565b600082905092915050565b600082821b905092915050565b600061611283836160ee565b8261611d8135614105565b9250600482101561615d576161587fffffffff00000000000000000000000000000000000000000000000000000000836004036008026160f9565b831692505b505092915050565b60006020828403121561617b5761617a6140fb565b5b60006161898482850161487c565b91505092915050565b6000602082840312156161a8576161a76140fb565b5b60006161b684828501614402565b91505092915050565b600067ffffffffffffffff8211156161da576161d96141db565b5b602082029050602081019050919050565b60006161fe6161f9846161bf565b61423b565b9050808382526020820190506020840283018581111561622157616220614698565b5b835b8181101561624a578061623688826143cc565b845260208401935050602081019050616223565b5050509392505050565b600082601f830112616269576162686141c0565b5b81356162798482602086016161eb565b91505092915050565b600067ffffffffffffffff82111561629d5761629c6141db565b5b602082029050602081019050919050565b60006162c16162bc84616282565b61423b565b905080838252602082019050602084028301858111156162e4576162e3614698565b5b835b8181101561632b57803567ffffffffffffffff811115616309576163086141c0565b5b80860161631689826142d8565b855260208501945050506020810190506162e6565b5050509392505050565b600082601f83011261634a576163496141c0565b5b813561635a8482602086016162ae565b91505092915050565b60008060006060848603121561637c5761637b6140fb565b5b600084013567ffffffffffffffff81111561639a57616399614100565b5b6163a686828701616254565b935050602084013567ffffffffffffffff8111156163c7576163c6614100565b5b6163d3868287016150de565b925050604084013567ffffffffffffffff8111156163f4576163f3614100565b5b61640086828701616335565b9150509250925092565b7f6163636f756e743a206e6f742066726f6d20456e747279506f696e7400000000600082015250565b6000616440601c83615275565b915061644b8261640a565b602082019050919050565b6000602082019050818103600083015261646f81616433565b9050919050565b600081905092915050565b50565b6000616491600083616476565b915061649c82616481565b600082019050919050565b60006164b282616484565b9150819050919050565b6164c58161418a565b81146164d057600080fd5b50565b6000815190506164e2816164bc565b92915050565b6000602082840312156164fe576164fd6140fb565b5b600061650c848285016164d3565b91505092915050565b600061652082614db0565b61652a8185616476565b935061653a818560208601614dcc565b80840191505092915050565b60006165528284616515565b915081905092915050565b7f2161646d696e0000000000000000000000000000000000000000000000000000600082015250565b6000616593600683615275565b915061659e8261655d565b602082019050919050565b600060208201905081810360008301526165c281616586565b9050919050565b60006040820190506165de6000830185614cff565b6165eb6020830184614359565b9392505050565b6000604082019050818103600083015261660c8185615286565b905081810360208301526166208184615286565b90509392505050565b600081905092915050565b61663d816143a3565b82525050565b600061664f8383616634565b60208301905092915050565b60006166678385616629565b935061667282615bc5565b8060005b858110156166ab576166888284615b16565b6166928882616643565b975061669d83615bcf565b925050600181019050616676565b5085925050509392505050565b60006166c582848661665b565b91508190509392505050565b6166da8161598b565b82525050565b6166e981614abc565b82525050565b600061014082019050616705600083018d614359565b616712602083018c614cff565b61671f604083018b6166d1565b61672c606083018a614359565b6167396080830189614669565b61674660a08301886166e0565b61675360c08301876166e0565b61676060e08301866166e0565b61676e6101008301856166e0565b61677c610120830184614359565b9b9a5050505050505050505050565b600082825260208201905092915050565b60006167a782614db0565b6167b1818561678b565b93506167c1818560208601614dcc565b6167ca816141ca565b840191505092915050565b60006040820190506167ea6000830185614cff565b81810360208301526167fc818461679c565b90509392505050565b600060a08201905061681a6000830188614359565b6168276020830187614359565b6168346040830186614359565b6168416060830185614669565b61684e6080830184614cff565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b60006168bd601883615275565b91506168c882616887565b602082019050919050565b600060208201905081810360008301526168ec816168b0565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000616929601f83615275565b9150616934826168f3565b602082019050919050565b600060208201905081810360008301526169588161691c565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b60006169bb602283615275565b91506169c68261695f565b604082019050919050565b600060208201905081810360008301526169ea816169ae565b9050919050565b60006169fc826143e1565b9150616a07836143e1565b925082821015616a1a57616a196156ac565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60008201527f6e74726163740000000000000000000000000000000000000000000000000000602082015250565b6000616ab0602683615275565b9150616abb82616a54565b604082019050919050565b60006020820190508181036000830152616adf81616aa3565b9050919050565b6000608082019050616afb6000830187614359565b616b0860208301866166d1565b616b156040830185614359565b616b226060830184614359565b9594505050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c01f45986875a650052d69ddb710a441ce161ad5c7fe9d20f876664fcbe181a564736f6c634300080c0033"; + diff --git a/src/test/smart-wallet/utils/AABenchmarkPrepare.sol b/src/test/smart-wallet/utils/AABenchmarkPrepare.sol new file mode 100644 index 000000000..554f3b4fa --- /dev/null +++ b/src/test/smart-wallet/utils/AABenchmarkPrepare.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.0; + +// Test utils +import "../../utils/BaseTest.sol"; + +// Account Abstraction setup for smart wallets. +import { IEntryPoint } from "contracts/prebuilts/account/utils/Entrypoint.sol"; + +import { AccountFactory } from "contracts/prebuilts/account/non-upgradeable/AccountFactory.sol"; +import "contracts/lib/TWStrings.sol"; + +import "forge-std/Test.sol"; + +contract AABenchmarkPrepare is BaseTest { + AccountFactory private accountFactory; + + function setUp() public override { + super.setUp(); + accountFactory = new AccountFactory(IEntryPoint(payable(address(0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789)))); + } + + function test_prepareBenchmarkFile() public { + address accountFactoryAddress = address(accountFactory); + bytes memory accountFactoryBytecode = accountFactoryAddress.code; + + address accountImplAddress = accountFactory.accountImplementation(); + bytes memory accountImplBytecode = accountImplAddress.code; + + string memory accountFactoryAddressString = string.concat( + "address constant THIRDWEB_ACCOUNT_FACTORY_ADDRESS = ", + TWStrings.toHexStringChecksummed(accountFactoryAddress), + ";" + ); + string memory accountFactoryBytecodeString = string.concat( + 'bytes constant THIRDWEB_ACCOUNT_FACTORY_BYTECODE = hex"', + TWStrings.toHexStringNoPrefix(accountFactoryBytecode), + '"', + ";" + ); + + string memory accountImplAddressString = string.concat( + "address constant THIRDWEB_ACCOUNT_IMPL_ADDRESS = ", + TWStrings.toHexStringChecksummed(accountImplAddress), + ";" + ); + string memory accountImplBytecodeString = string.concat( + 'bytes constant THIRDWEB_ACCOUNT_IMPL_BYTECODE = hex"', + TWStrings.toHexStringNoPrefix(accountImplBytecode), + '"', + ";" + ); + + string memory path = "src/test/smart-wallet/utils/AABenchmarkArtifacts.sol"; + + vm.removeFile(path); + + vm.writeLine(path, ""); + vm.writeLine(path, "pragma solidity ^0.8.0;"); + vm.writeLine(path, "interface ThirdwebAccountFactory {"); + vm.writeLine( + path, + " function createAccount(address _admin, bytes calldata _data) external returns (address);" + ); + vm.writeLine( + path, + " function getAddress(address _adminSigner, bytes calldata _data) external view returns (address);" + ); + vm.writeLine(path, "}"); + + vm.writeLine(path, "interface ThirdwebAccount {"); + vm.writeLine(path, " function execute(address _target, uint256 _value, bytes calldata _calldata) external;"); + vm.writeLine(path, "}"); + vm.writeLine(path, accountFactoryAddressString); + vm.writeLine(path, accountImplAddressString); + vm.writeLine(path, accountFactoryBytecodeString); + vm.writeLine(path, accountImplBytecodeString); + + vm.writeLine(path, ""); + } +} diff --git a/src/test/smart-wallet/utils/AABenchmarkTest.t.sol b/src/test/smart-wallet/utils/AABenchmarkTest.t.sol new file mode 100644 index 000000000..03f7fa9ed --- /dev/null +++ b/src/test/smart-wallet/utils/AABenchmarkTest.t.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.0; + +import "./AATestBase.sol"; +import { ThirdwebAccountFactory, ThirdwebAccount, THIRDWEB_ACCOUNT_FACTORY_ADDRESS, THIRDWEB_ACCOUNT_IMPL_ADDRESS, THIRDWEB_ACCOUNT_FACTORY_BYTECODE, THIRDWEB_ACCOUNT_IMPL_BYTECODE } from "./AABenchmarkArtifacts.sol"; + +contract ProfileThirdwebAccount is AAGasProfileBase { + ThirdwebAccountFactory factory; + + function setUp() external { + initializeTest("thirdwebAccount"); + factory = ThirdwebAccountFactory(THIRDWEB_ACCOUNT_FACTORY_ADDRESS); + vm.etch(address(factory), THIRDWEB_ACCOUNT_FACTORY_BYTECODE); + vm.etch(THIRDWEB_ACCOUNT_IMPL_ADDRESS, THIRDWEB_ACCOUNT_IMPL_BYTECODE); + setAccount(); + } + + function fillData( + address _to, + uint256 _value, + bytes memory _data + ) internal view override returns (bytes memory) { + return abi.encodeWithSelector(ThirdwebAccount.execute.selector, _to, _value, _data); + } + + function getSignature(UserOperation memory _op) internal view override returns (bytes memory) { + return signUserOpHash(key, _op); + } + + function createAccount(address _owner) internal override { + // if (address(account).code.length == 0) { + factory.createAccount(_owner, ""); + // } + } + + function getAccountAddr(address _owner) internal view override returns (IAccount) { + return IAccount(factory.getAddress(_owner, "")); + } + + function getInitCode(address _owner) internal view override returns (bytes memory) { + return abi.encodePacked(address(factory), abi.encodeWithSelector(factory.createAccount.selector, _owner, "")); + } + + function getDummySig(UserOperation memory _op) internal pure override returns (bytes memory) { + return + hex"fffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c"; + } +} diff --git a/src/test/smart-wallet/utils/AATestArtifacts.sol b/src/test/smart-wallet/utils/AATestArtifacts.sol new file mode 100644 index 000000000..66ecea693 --- /dev/null +++ b/src/test/smart-wallet/utils/AATestArtifacts.sol @@ -0,0 +1,9 @@ +pragma solidity ^0.8.0; + +bytes constant ENTRYPOINT_0_6_BYTECODE = hex"60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000007fc98430eaedbb6070b35b39d798725049088348165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f0000000000000000000000007fc98430eaedbb6070b35b39d7987250490883481690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f0000000000000000000000007fc98430eaedbb6070b35b39d7987250490883481690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c63430008110033"; + +bytes constant CREATOR_0_6_BYTECODE = hex"6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033"; + +bytes constant VERIFYINGPAYMASTER_BYTECODE = hex"6080604052600436106100e85760003560e01c8063a9a234091161008a578063c399ec8811610059578063c399ec881461028d578063d0e30db0146102a2578063f2fde38b146102aa578063f465c77e146102ca57600080fd5b8063a9a2340914610204578063b0d691fe14610224578063bb9fe6bf14610258578063c23a5cea1461026d57600080fd5b8063715018a6116100c6578063715018a6146101735780638da5cb5b1461018857806394d4ad60146101a657806394e1fc19146101d657600080fd5b80630396cb60146100ed578063205c28781461010257806323d9ac9b14610122575b600080fd5b6101006100fb366004610dc7565b6102f8565b005b34801561010e57600080fd5b5061010061011d366004610e09565b610383565b34801561012e57600080fd5b506101567f000000000000000000000000074bd8c57fe6f33ec5b580c92401f4feafc4443381565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561017f57600080fd5b506101006103f5565b34801561019457600080fd5b506000546001600160a01b0316610156565b3480156101b257600080fd5b506101c66101c1366004610e77565b610409565b60405161016a9493929190610eb9565b3480156101e257600080fd5b506101f66101f1366004610f39565b610446565b60405190815260200161016a565b34801561021057600080fd5b5061010061021f366004610f97565b610542565b34801561023057600080fd5b506101567f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d278981565b34801561026457600080fd5b5061010061055c565b34801561027957600080fd5b50610100610288366004610ff7565b6105d3565b34801561029957600080fd5b506101f6610659565b6101006106e9565b3480156102b657600080fd5b506101006102c5366004610ff7565b61074b565b3480156102d657600080fd5b506102ea6102e5366004611014565b6107c9565b60405161016a929190611062565b6103006107ed565b604051621cb65b60e51b815263ffffffff821660048201527f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d27896001600160a01b031690630396cb609034906024016000604051808303818588803b15801561036757600080fd5b505af115801561037b573d6000803e3d6000fd5b505050505050565b61038b6107ed565b60405163040b850f60e31b81526001600160a01b038381166004830152602482018390527f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d2789169063205c287890604401600060405180830381600087803b15801561036757600080fd5b6103fd6107ed565b6104076000610847565b565b600080368161041c6054601487896110b7565b81019061042991906110e1565b909450925061043b85605481896110b7565b949793965094505050565b6000833580602086013561045d6040880188611114565b60405161046b92919061115b565b6040519081900390206104816060890189611114565b60405161048f92919061115b565b604080519182900382206001600160a01b03909516602083015281019290925260608201526080808201929092529086013560a08083019190915286013560c08083019190915286013560e08083019190915286013561010080830191909152860135610120820152466101408201523061016082015265ffffffffffff80861661018083015284166101a08201526101c001604051602081830303815290604052805190602001209150509392505050565b61054a610897565b61055684848484610907565b50505050565b6105646107ed565b7f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d27896001600160a01b031663bb9fe6bf6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156105bf57600080fd5b505af1158015610556573d6000803e3d6000fd5b6105db6107ed565b60405163611d2e7560e11b81526001600160a01b0382811660048301527f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d2789169063c23a5cea90602401600060405180830381600087803b15801561063e57600080fd5b505af1158015610652573d6000803e3d6000fd5b5050505050565b6040516370a0823160e01b81523060048201526000907f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d27896001600160a01b0316906370a0823190602401602060405180830381865afa1580156106c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e4919061116b565b905090565b60405163b760faf960e01b81523060048201527f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d27896001600160a01b03169063b760faf99034906024016000604051808303818588803b15801561063e57600080fd5b6107536107ed565b6001600160a01b0381166107bd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b6107c681610847565b50565b606060006107d5610897565b6107e085858561093f565b915091505b935093915050565b6000546001600160a01b031633146104075760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107b4565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b336001600160a01b037f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d278916146104075760405162461bcd60e51b815260206004820152601560248201527414d95b99195c881b9bdd08115b9d1c9e541bda5b9d605a1b60448201526064016107b4565b60405162461bcd60e51b815260206004820152600d60248201526c6d757374206f7665727269646560981b60448201526064016107b4565b60606000808036816109586101c16101208b018b611114565b9296509094509250905060408114806109715750604181145b6109e5576040805162461bcd60e51b81526020600482015260248101919091527f566572696679696e675061796d61737465723a20696e76616c6964207369676e60448201527f6174757265206c656e67746820696e207061796d6173746572416e644461746160648201526084016107b4565b6000610a486109f58b8787610446565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b9050610a8a8184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610b1892505050565b6001600160a01b03167f000000000000000000000000074bd8c57fe6f33ec5b580c92401f4feafc444336001600160a01b031614610aed57610ace60018686610b3c565b60405180602001604052806000815250909650965050505050506107e5565b610af960008686610b3c565b6040805160208101909152600081529b909a5098505050505050505050565b6000806000610b278585610b74565b91509150610b3481610bb9565b509392505050565b600060d08265ffffffffffff16901b60a08465ffffffffffff16901b85610b64576000610b67565b60015b60ff161717949350505050565b6000808251604103610baa5760208301516040840151606085015160001a610b9e87828585610d03565b94509450505050610bb2565b506000905060025b9250929050565b6000816004811115610bcd57610bcd611184565b03610bd55750565b6001816004811115610be957610be9611184565b03610c365760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016107b4565b6002816004811115610c4a57610c4a611184565b03610c975760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016107b4565b6003816004811115610cab57610cab611184565b036107c65760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016107b4565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610d3a5750600090506003610dbe565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610d8e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610db757600060019250925050610dbe565b9150600090505b94509492505050565b600060208284031215610dd957600080fd5b813563ffffffff81168114610ded57600080fd5b9392505050565b6001600160a01b03811681146107c657600080fd5b60008060408385031215610e1c57600080fd5b8235610e2781610df4565b946020939093013593505050565b60008083601f840112610e4757600080fd5b50813567ffffffffffffffff811115610e5f57600080fd5b602083019150836020828501011115610bb257600080fd5b60008060208385031215610e8a57600080fd5b823567ffffffffffffffff811115610ea157600080fd5b610ead85828601610e35565b90969095509350505050565b600065ffffffffffff808716835280861660208401525060606040830152826060830152828460808401376000608084840101526080601f19601f850116830101905095945050505050565b60006101608284031215610f1857600080fd5b50919050565b803565ffffffffffff81168114610f3457600080fd5b919050565b600080600060608486031215610f4e57600080fd5b833567ffffffffffffffff811115610f6557600080fd5b610f7186828701610f05565b935050610f8060208501610f1e565b9150610f8e60408501610f1e565b90509250925092565b60008060008060608587031215610fad57600080fd5b843560038110610fbc57600080fd5b9350602085013567ffffffffffffffff811115610fd857600080fd5b610fe487828801610e35565b9598909750949560400135949350505050565b60006020828403121561100957600080fd5b8135610ded81610df4565b60008060006060848603121561102957600080fd5b833567ffffffffffffffff81111561104057600080fd5b61104c86828701610f05565b9660208601359650604090950135949350505050565b604081526000835180604084015260005b818110156110905760208187018101516060868401015201611073565b506000606082850101526060601f19601f8301168401019150508260208301529392505050565b600080858511156110c757600080fd5b838611156110d457600080fd5b5050820193919092039150565b600080604083850312156110f457600080fd5b6110fd83610f1e565b915061110b60208401610f1e565b90509250929050565b6000808335601e1984360301811261112b57600080fd5b83018035915067ffffffffffffffff82111561114657600080fd5b602001915036819003821315610bb257600080fd5b8183823760009101908152919050565b60006020828403121561117d57600080fd5b5051919050565b634e487b7160e01b600052602160045260246000fd"; + +address constant VERIFYINGPAYMASTER_ADDRESS = 0xe1Fb85Ec54767ED89252751F6667CF566b16f1F0; diff --git a/src/test/smart-wallet/utils/AATestBase.sol b/src/test/smart-wallet/utils/AATestBase.sol new file mode 100644 index 000000000..48da6dfe1 --- /dev/null +++ b/src/test/smart-wallet/utils/AATestBase.sol @@ -0,0 +1,285 @@ +pragma solidity ^0.8.0; + +import { IEntryPoint } from "contracts/prebuilts/account/interface/IEntrypoint.sol"; +import { UserOperation } from "contracts/prebuilts/account/utils/UserOperation.sol"; +import { IAccount } from "contracts/prebuilts/account/interface/IAccount.sol"; +import { VERIFYINGPAYMASTER_BYTECODE, VERIFYINGPAYMASTER_ADDRESS, ENTRYPOINT_0_6_BYTECODE, CREATOR_0_6_BYTECODE } from "./AATestArtifacts.sol"; + +import "contracts/external-deps/openzeppelin/utils/cryptography/ECDSA.sol"; +import "forge-std/Test.sol"; +import "forge-std/console.sol"; + +import { MockERC20 } from "../../mocks/MockERC20.sol"; + +interface IVerifyingPaymaster { + function owner() external view returns (address); + + function getHash( + UserOperation calldata userOp, + uint48 validUntil, + uint48 validAfter + ) external view returns (bytes32); +} + +interface VmModified { + function cool(address _target) external; + + function keyExists(string calldata, string calldata) external returns (bool); + + function parseJsonKeys(string calldata json, string calldata key) external pure returns (string[] memory keys); +} + +uint256 constant OV_FIXED = 21000; +uint256 constant OV_PER_USEROP = 18300; +uint256 constant OV_PER_WORD = 4; +uint256 constant OV_PER_ZERO_BYTE = 4; +uint256 constant OV_PER_NONZERO_BYTE = 16; + +abstract contract AAGasProfileBase is Test { + string public name; + string public scenarioName; + uint256 sum; + string jsonObj; + IEntryPoint public entryPoint; + address payable public beneficiary; + IAccount public account; + address public owner; + uint256 public key; + IVerifyingPaymaster public paymaster; + address public verifier; + uint256 public verifierKey; + bool public writeGasProfile = false; + + function(UserOperation memory) internal view returns (bytes memory) paymasterData; + function(UserOperation memory) internal view returns (bytes memory) dummyPaymasterData; + + function initializeTest(string memory _name) internal { + writeGasProfile = vm.envOr("WRITE_GAS_PROFILE", false); + name = _name; + entryPoint = IEntryPoint(payable(address(0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789))); + vm.etch(address(entryPoint), ENTRYPOINT_0_6_BYTECODE); + vm.etch(0x7fc98430eAEdbb6070B35B39D798725049088348, CREATOR_0_6_BYTECODE); + beneficiary = payable(makeAddr("beneficiary")); + vm.deal(beneficiary, 1e18); + paymasterData = emptyPaymasterAndData; + dummyPaymasterData = emptyPaymasterAndData; + (verifier, verifierKey) = makeAddrAndKey("VERIFIER"); + paymaster = IVerifyingPaymaster(VERIFYINGPAYMASTER_ADDRESS); + vm.etch(address(paymaster), VERIFYINGPAYMASTER_BYTECODE); + vm.store(address(paymaster), bytes32(0), bytes32(uint256(uint160(verifier)))); + } + + function setAccount() internal { + (owner, key) = makeAddrAndKey("Owner"); + account = getAccountAddr(owner); + vm.deal(address(account), 1e18); + } + + function fillUserOp(bytes memory _data) internal view returns (UserOperation memory op) { + op.sender = address(account); + op.nonce = entryPoint.getNonce(address(account), 0); + if (address(account).code.length == 0) { + op.initCode = getInitCode(owner); + } + op.callData = _data; + op.callGasLimit = 1000000; + op.verificationGasLimit = 1000000; + op.preVerificationGas = 21000; + op.maxFeePerGas = 1; + op.maxPriorityFeePerGas = 1; + op.signature = getDummySig(op); + op.paymasterAndData = dummyPaymasterData(op); + op.preVerificationGas = calculatePreVerificationGas(op); + op.paymasterAndData = paymasterData(op); + op.signature = getSignature(op); + } + + function signUserOpHash(uint256 _key, UserOperation memory _op) internal view returns (bytes memory signature) { + bytes32 hash = entryPoint.getUserOpHash(_op); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_key, ECDSA.toEthSignedMessageHash(hash)); + signature = abi.encodePacked(r, s, v); + } + + function executeUserOp( + UserOperation memory _op, + string memory _test, + uint256 _value + ) internal { + UserOperation[] memory ops = new UserOperation[](1); + ops[0] = _op; + uint256 eth_before; + if (_op.paymasterAndData.length > 0) { + eth_before = entryPoint.balanceOf(address(paymaster)); + } else { + eth_before = entryPoint.balanceOf(address(account)) + address(account).balance; + } + // vm.cool to be introduced to foundry + //VmModified(address(vm)).cool(address(entryPoint)); + //VmModified(address(vm)).cool(address(account)); + entryPoint.handleOps(ops, beneficiary); + uint256 eth_after; + if (_op.paymasterAndData.length > 0) { + eth_after = entryPoint.balanceOf(address(paymaster)); + } else { + eth_after = entryPoint.balanceOf(address(account)) + address(account).balance + _value; + } + if (!writeGasProfile) { + console.log("case - %s", _test); + console.log(" gasUsed : ", eth_before - eth_after); + console.log(" calldatacost : ", calldataCost(pack(_op))); + } + if (writeGasProfile && bytes(scenarioName).length > 0) { + uint256 gasUsed = eth_before - eth_after; + vm.serializeUint(jsonObj, _test, gasUsed); + sum += gasUsed; + } + } + + function testCreation() internal { + UserOperation memory op = fillUserOp(fillData(address(0), 0, "")); + executeUserOp(op, "creation", 0); + } + + function testTransferNative(address _recipient, uint256 _amount) internal { + vm.skip(writeGasProfile); + createAccount(owner); + _amount = bound(_amount, 1, address(account).balance / 2); + UserOperation memory op = fillUserOp(fillData(_recipient, _amount, "")); + executeUserOp(op, "native", _amount); + } + + function testTransferNative() internal { + createAccount(owner); + uint256 amount = 5e17; + address recipient = makeAddr("recipient"); + UserOperation memory op = fillUserOp(fillData(recipient, amount, "")); + executeUserOp(op, "native", amount); + } + + function testTransferERC20() internal { + createAccount(owner); + MockERC20 mockERC20 = new MockERC20(); + mockERC20.mint(address(account), 1e18); + uint256 amount = 5e17; + address recipient = makeAddr("recipient"); + uint256 balance = mockERC20.balanceOf(recipient); + UserOperation memory op = fillUserOp( + fillData(address(mockERC20), 0, abi.encodeWithSelector(mockERC20.transfer.selector, recipient, amount)) + ); + executeUserOp(op, "erc20", 0); + assertEq(mockERC20.balanceOf(recipient), balance + amount); + } + + function testBenchmark1Vanila() external { + scenarioName = "vanila"; + jsonObj = string(abi.encodePacked(scenarioName, " ", name)); + testCreation(); + testTransferNative(); + testTransferERC20(); + if (writeGasProfile) { + string memory res = vm.serializeUint(jsonObj, "sum", sum); + console.log(res); + vm.writeJson(res, string.concat("./results/", scenarioName, "_", name, ".json")); + } + } + + function testBenchmark2Paymaster() external { + scenarioName = "paymaster"; + jsonObj = string(abi.encodePacked(scenarioName, " ", name)); + entryPoint.depositTo{ value: 100e18 }(address(paymaster)); + paymasterData = validatePaymasterAndData; + dummyPaymasterData = getDummyPaymasterAndData; + testCreation(); + testTransferNative(); + testTransferERC20(); + if (writeGasProfile) { + string memory res = vm.serializeUint(jsonObj, "sum", sum); + console.log(res); + vm.writeJson(res, string.concat("./results/", scenarioName, "_", name, ".json")); + } + } + + function testBenchmark3Deposit() external { + scenarioName = "deposit"; + jsonObj = string(abi.encodePacked(scenarioName, " ", name)); + entryPoint.depositTo{ value: 100e18 }(address(account)); + testCreation(); + testTransferNative(); + testTransferERC20(); + if (writeGasProfile) { + string memory res = vm.serializeUint(jsonObj, "sum", sum); + console.log(res); + vm.writeJson(res, string.concat("./results/", scenarioName, "_", name, ".json")); + } + } + + function emptyPaymasterAndData(UserOperation memory _op) internal pure returns (bytes memory ret) {} + + function validatePaymasterAndData(UserOperation memory _op) internal view returns (bytes memory ret) { + bytes32 hash = paymaster.getHash(_op, 0, 0); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(verifierKey, ECDSA.toEthSignedMessageHash(hash)); + ret = abi.encodePacked(address(paymaster), uint256(0), uint256(0), r, s, uint8(v)); + } + + function getDummyPaymasterAndData(UserOperation memory _op) internal view returns (bytes memory ret) { + ret = abi.encodePacked( + address(paymaster), + uint256(0), + uint256(0), + hex"fffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c" + ); + } + + function pack(UserOperation memory _op) internal pure returns (bytes memory) { + bytes memory packed = abi.encode( + _op.sender, + _op.nonce, + _op.initCode, + _op.callData, + _op.callGasLimit, + _op.verificationGasLimit, + _op.preVerificationGas, + _op.maxFeePerGas, + _op.maxPriorityFeePerGas, + _op.paymasterAndData, + _op.signature + ); + return packed; + } + + function calldataCost(bytes memory packed) internal view returns (uint256) { + uint256 cost = 0; + for (uint256 i = 0; i < packed.length; i++) { + if (packed[i] == 0) { + cost += OV_PER_ZERO_BYTE; + } else { + cost += OV_PER_NONZERO_BYTE; + } + } + return cost; + } + + // NOTE: this can vary depending on the bundler, this equation is referencing eth-infinitism bundler's pvg calculation + function calculatePreVerificationGas(UserOperation memory _op) internal view returns (uint256) { + bytes memory packed = pack(_op); + uint256 calculated = OV_FIXED + OV_PER_USEROP + (OV_PER_WORD * (packed.length + 31)) / 32; + calculated += calldataCost(packed); + return calculated; + } + + function createAccount(address _owner) internal virtual; + + function getSignature(UserOperation memory _op) internal view virtual returns (bytes memory); + + function getDummySig(UserOperation memory _op) internal pure virtual returns (bytes memory); + + function fillData( + address _to, + uint256 _amount, + bytes memory _data + ) internal view virtual returns (bytes memory); + + function getAccountAddr(address _owner) internal view virtual returns (IAccount _account); + + function getInitCode(address _owner) internal view virtual returns (bytes memory); +}