- Contract name:
- Multicall3
- Optimization enabled
- true
- Compiler version
- v0.8.12+commit.f00d7308
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2023-01-16T08:49:13.150751Z
Contract source code
// SPDX-License-Identifier: MIT pragma solidity 0.8.12; /// @title Multicall3 /// @notice Aggregate results from multiple function calls /// @dev Multicall & Multicall2 backwards-compatible /// @dev Aggregate methods are marked `payable` to save 24 gas per call /// @author Michael Elliot <[email protected]> /// @author Joshua Levine <[email protected]> /// @author Nick Johnson <[email protected]> /// @author Andreas Bigger <[email protected]> /// @author Matt Solomon <[email protected]> contract Multicall3 { struct Call { address target; bytes callData; } struct Call3 { address target; bool allowFailure; bytes callData; } struct Call3Value { address target; bool allowFailure; uint256 value; bytes callData; } struct Result { bool success; bytes returnData; } /// @notice Backwards-compatible call aggregation with Multicall /// @param calls An array of Call structs /// @return blockNumber The block number where the calls were executed /// @return returnData An array of bytes containing the responses function aggregate(Call[] calldata calls) public payable returns (uint256 blockNumber, bytes[] memory returnData) { blockNumber = block.number; uint256 length = calls.length; returnData = new bytes[](length); Call calldata call; for (uint256 i = 0; i < length;) { bool success; call = calls[i]; (success, returnData[i]) = call.target.call(call.callData); require(success, "Multicall3: call failed"); unchecked { ++i; } } } /// @notice Backwards-compatible with Multicall2 /// @notice Aggregate calls without requiring success /// @param requireSuccess If true, require all calls to succeed /// @param calls An array of Call structs /// @return returnData An array of Result structs function tryAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (Result[] memory returnData) { uint256 length = calls.length; returnData = new Result[](length); Call calldata call; for (uint256 i = 0; i < length;) { Result memory result = returnData[i]; call = calls[i]; (result.success, result.returnData) = call.target.call(call.callData); if (requireSuccess) require(result.success, "Multicall3: call failed"); unchecked { ++i; } } } /// @notice Backwards-compatible with Multicall2 /// @notice Aggregate calls and allow failures using tryAggregate /// @param calls An array of Call structs /// @return blockNumber The block number where the calls were executed /// @return blockHash The hash of the block where the calls were executed /// @return returnData An array of Result structs function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) { blockNumber = block.number; blockHash = blockhash(block.number); returnData = tryAggregate(requireSuccess, calls); } /// @notice Backwards-compatible with Multicall2 /// @notice Aggregate calls and allow failures using tryAggregate /// @param calls An array of Call structs /// @return blockNumber The block number where the calls were executed /// @return blockHash The hash of the block where the calls were executed /// @return returnData An array of Result structs function blockAndAggregate(Call[] calldata calls) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) { (blockNumber, blockHash, returnData) = tryBlockAndAggregate(true, calls); } /// @notice Aggregate calls, ensuring each returns success if required /// @param calls An array of Call3 structs /// @return returnData An array of Result structs function aggregate3(Call3[] calldata calls) public payable returns (Result[] memory returnData) { uint256 length = calls.length; returnData = new Result[](length); Call3 calldata calli; for (uint256 i = 0; i < length;) { Result memory result = returnData[i]; calli = calls[i]; (result.success, result.returnData) = calli.target.call(calli.callData); assembly { // Revert if the call fails and failure is not allowed // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)` if iszero(or(calldataload(add(calli, 0x20)), mload(result))) { // set "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000) // set data offset mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020) // set length of revert string mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017) // set revert string: bytes32(abi.encodePacked("Multicall3: call failed")) mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000) revert(0x00, 0x64) } } unchecked { ++i; } } } /// @notice Aggregate calls with a msg value /// @notice Reverts if msg.value is less than the sum of the call values /// @param calls An array of Call3Value structs /// @return returnData An array of Result structs function aggregate3Value(Call3Value[] calldata calls) public payable returns (Result[] memory returnData) { uint256 valAccumulator; uint256 length = calls.length; returnData = new Result[](length); Call3Value calldata calli; for (uint256 i = 0; i < length;) { Result memory result = returnData[i]; calli = calls[i]; uint256 val = calli.value; // Humanity will be a Type V Kardashev Civilization before this overflows - andreas // ~ 10^25 Wei in existence << ~ 10^76 size uint fits in a uint256 unchecked { valAccumulator += val; } (result.success, result.returnData) = calli.target.call{value: val}(calli.callData); assembly { // Revert if the call fails and failure is not allowed // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)` if iszero(or(calldataload(add(calli, 0x20)), mload(result))) { // set "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000) // set data offset mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020) // set length of revert string mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017) // set revert string: bytes32(abi.encodePacked("Multicall3: call failed")) mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000) revert(0x00, 0x84) } } unchecked { ++i; } } // Finally, make sure the msg.value = SUM(call[0...i].value) require(msg.value == valAccumulator, "Multicall3: value mismatch"); } /// @notice Returns the block hash for the given block number /// @param blockNumber The block number function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) { blockHash = blockhash(blockNumber); } /// @notice Returns the block number function getBlockNumber() public view returns (uint256 blockNumber) { blockNumber = block.number; } /// @notice Returns the block coinbase function getCurrentBlockCoinbase() public view returns (address coinbase) { coinbase = block.coinbase; } /// @notice Returns the block difficulty function getCurrentBlockDifficulty() public view returns (uint256 difficulty) { difficulty = block.difficulty; } /// @notice Returns the block gas limit function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) { gaslimit = block.gaslimit; } /// @notice Returns the block timestamp function getCurrentBlockTimestamp() public view returns (uint256 timestamp) { timestamp = block.timestamp; } /// @notice Returns the (ETH) balance of a given address function getEthBalance(address addr) public view returns (uint256 balance) { balance = addr.balance; } /// @notice Returns the block hash of the last block function getLastBlockHash() public view returns (bytes32 blockHash) { unchecked { blockHash = blockhash(block.number - 1); } } /// @notice Gets the base fee of the given block /// @notice Can revert if the BASEFEE opcode is not implemented by the given chain function getBasefee() public view returns (uint256 basefee) { basefee = block.basefee; } /// @notice Returns the chain id function getChainId() public view returns (uint256 chainid) { chainid = block.chainid; } }
Contract ABI
[{"type":"function","stateMutability":"payable","outputs":[{"type":"uint256","name":"blockNumber","internalType":"uint256"},{"type":"bytes[]","name":"returnData","internalType":"bytes[]"}],"name":"aggregate","inputs":[{"type":"tuple[]","name":"calls","internalType":"struct Multicall3.Call[]","components":[{"type":"address","name":"target","internalType":"address"},{"type":"bytes","name":"callData","internalType":"bytes"}]}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"tuple[]","name":"returnData","internalType":"struct Multicall3.Result[]","components":[{"type":"bool","name":"success","internalType":"bool"},{"type":"bytes","name":"returnData","internalType":"bytes"}]}],"name":"aggregate3","inputs":[{"type":"tuple[]","name":"calls","internalType":"struct Multicall3.Call3[]","components":[{"type":"address","name":"target","internalType":"address"},{"type":"bool","name":"allowFailure","internalType":"bool"},{"type":"bytes","name":"callData","internalType":"bytes"}]}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"tuple[]","name":"returnData","internalType":"struct Multicall3.Result[]","components":[{"type":"bool","name":"success","internalType":"bool"},{"type":"bytes","name":"returnData","internalType":"bytes"}]}],"name":"aggregate3Value","inputs":[{"type":"tuple[]","name":"calls","internalType":"struct Multicall3.Call3Value[]","components":[{"type":"address","name":"target","internalType":"address"},{"type":"bool","name":"allowFailure","internalType":"bool"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"bytes","name":"callData","internalType":"bytes"}]}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"uint256","name":"blockNumber","internalType":"uint256"},{"type":"bytes32","name":"blockHash","internalType":"bytes32"},{"type":"tuple[]","name":"returnData","internalType":"struct Multicall3.Result[]","components":[{"type":"bool","name":"success","internalType":"bool"},{"type":"bytes","name":"returnData","internalType":"bytes"}]}],"name":"blockAndAggregate","inputs":[{"type":"tuple[]","name":"calls","internalType":"struct Multicall3.Call[]","components":[{"type":"address","name":"target","internalType":"address"},{"type":"bytes","name":"callData","internalType":"bytes"}]}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"basefee","internalType":"uint256"}],"name":"getBasefee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"blockHash","internalType":"bytes32"}],"name":"getBlockHash","inputs":[{"type":"uint256","name":"blockNumber","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"blockNumber","internalType":"uint256"}],"name":"getBlockNumber","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"chainid","internalType":"uint256"}],"name":"getChainId","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"coinbase","internalType":"address"}],"name":"getCurrentBlockCoinbase","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"difficulty","internalType":"uint256"}],"name":"getCurrentBlockDifficulty","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"gaslimit","internalType":"uint256"}],"name":"getCurrentBlockGasLimit","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"timestamp","internalType":"uint256"}],"name":"getCurrentBlockTimestamp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"balance","internalType":"uint256"}],"name":"getEthBalance","inputs":[{"type":"address","name":"addr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"blockHash","internalType":"bytes32"}],"name":"getLastBlockHash","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[{"type":"tuple[]","name":"returnData","internalType":"struct Multicall3.Result[]","components":[{"type":"bool","name":"success","internalType":"bool"},{"type":"bytes","name":"returnData","internalType":"bytes"}]}],"name":"tryAggregate","inputs":[{"type":"bool","name":"requireSuccess","internalType":"bool"},{"type":"tuple[]","name":"calls","internalType":"struct Multicall3.Call[]","components":[{"type":"address","name":"target","internalType":"address"},{"type":"bytes","name":"callData","internalType":"bytes"}]}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"uint256","name":"blockNumber","internalType":"uint256"},{"type":"bytes32","name":"blockHash","internalType":"bytes32"},{"type":"tuple[]","name":"returnData","internalType":"struct Multicall3.Result[]","components":[{"type":"bool","name":"success","internalType":"bool"},{"type":"bytes","name":"returnData","internalType":"bytes"}]}],"name":"tryBlockAndAggregate","inputs":[{"type":"bool","name":"requireSuccess","internalType":"bool"},{"type":"tuple[]","name":"calls","internalType":"struct Multicall3.Call[]","components":[{"type":"address","name":"target","internalType":"address"},{"type":"bytes","name":"callData","internalType":"bytes"}]}]}]
Contract Creation Code
0x608060405234801561001057600080fd5b50610cd6806100206000396000f3fe6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461022f578063bce38bd71461024a578063c3077fa91461025d578063ee82ac5e1461027057600080fd5b80634d2301cc146101ce57806372425d9d146101f657806382ad56cb1461020957806386d516e81461021c57600080fd5b80633408e470116100c65780633408e47014610173578063399542e9146101865780633e64a696146101a857806342cbb15c146101bb57600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d61012836600461098c565b61028f565b6040516101119190610a89565b61014d61014836600461098c565b61047d565b604051610111929190610aa3565b34801561016757600080fd5b50436000190140610107565b34801561017f57600080fd5b5046610107565b610199610194366004610b0d565b6105f1565b60405161011193929190610b67565b3480156101b457600080fd5b5048610107565b3480156101c757600080fd5b5043610107565b3480156101da57600080fd5b506101076101e9366004610b8f565b6001600160a01b03163190565b34801561020257600080fd5b5044610107565b61012d61021736600461098c565b61060c565b34801561022857600080fd5b5045610107565b34801561023b57600080fd5b50604051418152602001610111565b61012d610258366004610b0d565b61078e565b61019961026b36600461098c565b610921565b34801561027c57600080fd5b5061010761028b366004610bb8565b4090565b60606000828067ffffffffffffffff8111156102ad576102ad610bd1565b6040519080825280602002602001820160405280156102f357816020015b6040805180820190915260008152606060208201528152602001906001900390816102cb5790505b5092503660005b8281101561041f57600085828151811061031657610316610be7565b6020026020010151905087878381811061033257610332610be7565b90506020028101906103449190610bfd565b60408101359586019590935061035d6020850185610b8f565b6001600160a01b0316816103746060870187610c1d565b604051610382929190610c64565b60006040518083038185875af1925050503d80600081146103bf576040519150601f19603f3d011682016040523d82523d6000602084013e6103c4565b606091505b5060208085019190915290151580845290850135176104155762461bcd60e51b6000526020600452601760245276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b60445260846000fd5b50506001016102fa565b508234146104745760405162461bcd60e51b815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561049a5761049a610bd1565b6040519080825280602002602001820160405280156104cd57816020015b60608152602001906001900390816104b85790505b5091503660005b828110156105e75760008787838181106104f0576104f0610be7565b90506020028101906105029190610c74565b92506105116020840184610b8f565b6001600160a01b03166105276020850185610c1d565b604051610535929190610c64565b6000604051808303816000865af19150503d8060008114610572576040519150601f19603f3d011682016040523d82523d6000602084013e610577565b606091505b5086848151811061058a5761058a610be7565b60209081029190910101529050806105de5760405162461bcd60e51b8152602060048201526017602482015276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b604482015260640161046b565b506001016104d4565b5050509250929050565b438040606061060186868661078e565b905093509350939050565b6060818067ffffffffffffffff81111561062857610628610bd1565b60405190808252806020026020018201604052801561066e57816020015b6040805180820190915260008152606060208201528152602001906001900390816106465790505b5091503660005b8281101561047457600084828151811061069157610691610be7565b602002602001015190508686838181106106ad576106ad610be7565b90506020028101906106bf9190610c8a565b92506106ce6020840184610b8f565b6001600160a01b03166106e46040850185610c1d565b6040516106f2929190610c64565b6000604051808303816000865af19150503d806000811461072f576040519150601f19603f3d011682016040523d82523d6000602084013e610734565b606091505b5060208084019190915290151580835290840135176107855762461bcd60e51b6000526020600452601760245276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b60445260646000fd5b50600101610675565b6060818067ffffffffffffffff8111156107aa576107aa610bd1565b6040519080825280602002602001820160405280156107f057816020015b6040805180820190915260008152606060208201528152602001906001900390816107c85790505b5091503660005b8281101561091757600084828151811061081357610813610be7565b6020026020010151905086868381811061082f5761082f610be7565b90506020028101906108419190610c74565b92506108506020840184610b8f565b6001600160a01b03166108666020850185610c1d565b604051610874929190610c64565b6000604051808303816000865af19150503d80600081146108b1576040519150601f19603f3d011682016040523d82523d6000602084013e6108b6565b606091505b50602083015215158152871561090e57805161090e5760405162461bcd60e51b8152602060048201526017602482015276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b604482015260640161046b565b506001016107f7565b5050509392505050565b6000806060610932600186866105f1565b919790965090945092505050565b60008083601f84011261095257600080fd5b50813567ffffffffffffffff81111561096a57600080fd5b6020830191508360208260051b850101111561098557600080fd5b9250929050565b6000806020838503121561099f57600080fd5b823567ffffffffffffffff8111156109b657600080fd5b6109c285828601610940565b90969095509350505050565b6000815180845260005b818110156109f4576020818501810151868301820152016109d8565b81811115610a06576000602083870101525b50601f01601f19169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610a7c57858303601f1901895281518051151584528401516040858501819052610a68818601836109ce565b9a86019a9450505090830190600101610a38565b5090979650505050505050565b602081526000610a9c6020830184610a1b565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610aff57605f19888703018452610aed8683516109ce565b95509284019290840190600101610ad1565b509398975050505050505050565b600080600060408486031215610b2257600080fd5b83358015158114610b3257600080fd5b9250602084013567ffffffffffffffff811115610b4e57600080fd5b610b5a86828701610940565b9497909650939450505050565b838152826020820152606060408201526000610b866060830184610a1b565b95945050505050565b600060208284031215610ba157600080fd5b81356001600160a01b0381168114610a9c57600080fd5b600060208284031215610bca57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60008235607e19833603018112610c1357600080fd5b9190910192915050565b6000808335601e19843603018112610c3457600080fd5b83018035915067ffffffffffffffff821115610c4f57600080fd5b60200191503681900382131561098557600080fd5b8183823760009101908152919050565b60008235603e19833603018112610c1357600080fd5b60008235605e19833603018112610c1357600080fdfea264697066735822122042e92b6801eb267dfe24a891029f12b0f790df0e239e424844e6bed25ed4551a64736f6c634300080c0033
Deployed ByteCode
0x6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461022f578063bce38bd71461024a578063c3077fa91461025d578063ee82ac5e1461027057600080fd5b80634d2301cc146101ce57806372425d9d146101f657806382ad56cb1461020957806386d516e81461021c57600080fd5b80633408e470116100c65780633408e47014610173578063399542e9146101865780633e64a696146101a857806342cbb15c146101bb57600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d61012836600461098c565b61028f565b6040516101119190610a89565b61014d61014836600461098c565b61047d565b604051610111929190610aa3565b34801561016757600080fd5b50436000190140610107565b34801561017f57600080fd5b5046610107565b610199610194366004610b0d565b6105f1565b60405161011193929190610b67565b3480156101b457600080fd5b5048610107565b3480156101c757600080fd5b5043610107565b3480156101da57600080fd5b506101076101e9366004610b8f565b6001600160a01b03163190565b34801561020257600080fd5b5044610107565b61012d61021736600461098c565b61060c565b34801561022857600080fd5b5045610107565b34801561023b57600080fd5b50604051418152602001610111565b61012d610258366004610b0d565b61078e565b61019961026b36600461098c565b610921565b34801561027c57600080fd5b5061010761028b366004610bb8565b4090565b60606000828067ffffffffffffffff8111156102ad576102ad610bd1565b6040519080825280602002602001820160405280156102f357816020015b6040805180820190915260008152606060208201528152602001906001900390816102cb5790505b5092503660005b8281101561041f57600085828151811061031657610316610be7565b6020026020010151905087878381811061033257610332610be7565b90506020028101906103449190610bfd565b60408101359586019590935061035d6020850185610b8f565b6001600160a01b0316816103746060870187610c1d565b604051610382929190610c64565b60006040518083038185875af1925050503d80600081146103bf576040519150601f19603f3d011682016040523d82523d6000602084013e6103c4565b606091505b5060208085019190915290151580845290850135176104155762461bcd60e51b6000526020600452601760245276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b60445260846000fd5b50506001016102fa565b508234146104745760405162461bcd60e51b815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561049a5761049a610bd1565b6040519080825280602002602001820160405280156104cd57816020015b60608152602001906001900390816104b85790505b5091503660005b828110156105e75760008787838181106104f0576104f0610be7565b90506020028101906105029190610c74565b92506105116020840184610b8f565b6001600160a01b03166105276020850185610c1d565b604051610535929190610c64565b6000604051808303816000865af19150503d8060008114610572576040519150601f19603f3d011682016040523d82523d6000602084013e610577565b606091505b5086848151811061058a5761058a610be7565b60209081029190910101529050806105de5760405162461bcd60e51b8152602060048201526017602482015276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b604482015260640161046b565b506001016104d4565b5050509250929050565b438040606061060186868661078e565b905093509350939050565b6060818067ffffffffffffffff81111561062857610628610bd1565b60405190808252806020026020018201604052801561066e57816020015b6040805180820190915260008152606060208201528152602001906001900390816106465790505b5091503660005b8281101561047457600084828151811061069157610691610be7565b602002602001015190508686838181106106ad576106ad610be7565b90506020028101906106bf9190610c8a565b92506106ce6020840184610b8f565b6001600160a01b03166106e46040850185610c1d565b6040516106f2929190610c64565b6000604051808303816000865af19150503d806000811461072f576040519150601f19603f3d011682016040523d82523d6000602084013e610734565b606091505b5060208084019190915290151580835290840135176107855762461bcd60e51b6000526020600452601760245276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b60445260646000fd5b50600101610675565b6060818067ffffffffffffffff8111156107aa576107aa610bd1565b6040519080825280602002602001820160405280156107f057816020015b6040805180820190915260008152606060208201528152602001906001900390816107c85790505b5091503660005b8281101561091757600084828151811061081357610813610be7565b6020026020010151905086868381811061082f5761082f610be7565b90506020028101906108419190610c74565b92506108506020840184610b8f565b6001600160a01b03166108666020850185610c1d565b604051610874929190610c64565b6000604051808303816000865af19150503d80600081146108b1576040519150601f19603f3d011682016040523d82523d6000602084013e6108b6565b606091505b50602083015215158152871561090e57805161090e5760405162461bcd60e51b8152602060048201526017602482015276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b604482015260640161046b565b506001016107f7565b5050509392505050565b6000806060610932600186866105f1565b919790965090945092505050565b60008083601f84011261095257600080fd5b50813567ffffffffffffffff81111561096a57600080fd5b6020830191508360208260051b850101111561098557600080fd5b9250929050565b6000806020838503121561099f57600080fd5b823567ffffffffffffffff8111156109b657600080fd5b6109c285828601610940565b90969095509350505050565b6000815180845260005b818110156109f4576020818501810151868301820152016109d8565b81811115610a06576000602083870101525b50601f01601f19169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610a7c57858303601f1901895281518051151584528401516040858501819052610a68818601836109ce565b9a86019a9450505090830190600101610a38565b5090979650505050505050565b602081526000610a9c6020830184610a1b565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610aff57605f19888703018452610aed8683516109ce565b95509284019290840190600101610ad1565b509398975050505050505050565b600080600060408486031215610b2257600080fd5b83358015158114610b3257600080fd5b9250602084013567ffffffffffffffff811115610b4e57600080fd5b610b5a86828701610940565b9497909650939450505050565b838152826020820152606060408201526000610b866060830184610a1b565b95945050505050565b600060208284031215610ba157600080fd5b81356001600160a01b0381168114610a9c57600080fd5b600060208284031215610bca57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60008235607e19833603018112610c1357600080fd5b9190910192915050565b6000808335601e19843603018112610c3457600080fd5b83018035915067ffffffffffffffff821115610c4f57600080fd5b60200191503681900382131561098557600080fd5b8183823760009101908152919050565b60008235603e19833603018112610c1357600080fd5b60008235605e19833603018112610c1357600080fdfea264697066735822122042e92b6801eb267dfe24a891029f12b0f790df0e239e424844e6bed25ed4551a64736f6c634300080c0033