Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- HashedTimeLockEther
- Optimization enabled
- true
- Compiler version
- v0.8.23+commit.f704f362
- Optimization runs
- 200
- EVM Version
- paris
- Verified at
- 2024-08-15T11:25:49.554270Z
contracts/HashedTimeLockEther.sol
/* _ __ _____ | | __ _ _ _ ___ _ __ _____ ____ _ _ __ \ \ / ( _ ) | | / _` | | | |/ _ \ '__/ __\ \ /\ / / _` | '_ \ \ \ / // _ \ | |__| (_| | |_| | __/ | \__ \\ V V / (_| | |_) | \ V /| (_) | |_____\__,_|\__, |\___|_| |___/ \_/\_/ \__,_| .__/ \_/ \___/ |___/ |_| */ // SPDX-License-Identifier: MIT pragma solidity 0.8.23; interface IMessenger { function notify( bytes32 commitId, bytes32 hashlock, string memory dstChain, string memory dstAsset, string memory dstAddress, string memory srcAsset, address payable sender, address payable srcReceiver, uint256 amount, uint256 timelock, address tokenContract ) external; } contract HashedTimeLockEther { error FundsNotSent(); error NotFutureTimelock(); error NotPassedTimelock(); error LockAlreadyExists(); error CommitIdAlreadyExists(); error LockNotExists(); error HashlockNotMatch(); error AlreadyRedeemed(); error AlreadyUnlocked(); error NoMessenger(); error CommitmentNotExists(); error AlreadyLocked(); error AlreadyUncommitted(); error NoAllowance(); struct HTLC { string dstAddress; string dstChain; string dstAsset; string srcAsset; address payable sender; address payable srcReceiver; bytes32 hashlock; uint256 secret; uint256 amount; uint256 timelock; bool redeemed; bool unlocked; } struct PHTLC { string dstAddress; string dstChain; string dstAsset; string srcAsset; address payable sender; address payable srcReceiver; bytes32 lockId; uint timelock; uint amount; address messenger; bool locked; bool uncommitted; } event TokenCommitted( bytes32 commitId, string[] hopChains, string[] hopAssets, string[] hopAddresses, string dstChain, string dstAddress, string dstAsset, address sender, address srcReceiver, string srcAsset, uint amount, uint timelock, address messenger ); event TokenLocked( bytes32 indexed hashlock, string dstChain, string dstAddress, string dstAsset, address indexed sender, address indexed srcReceiver, string srcAsset, uint amount, uint timelock, address messenger, bytes32 commitId ); event LowLevelErrorOccurred(bytes lowLevelData); event TokenUnlocked(bytes32 indexed lockId); event TokenUncommitted(bytes32 indexed commitId); event TokenRedeemed(bytes32 indexed lockId, address redeemAddress); modifier _committed(bytes32 commitId) { if (!hasPHTLC(commitId)) revert CommitmentNotExists(); _; } modifier _locked(bytes32 lockId) { if (!hasHTLC(lockId)) revert LockNotExists(); _; } mapping(bytes32 => HTLC) locks; mapping(bytes32 => PHTLC) commits; mapping(bytes32 => bytes32) commitIdToLockId; bytes32[] lockIds; bytes32[] commitIds; bytes32 blockHash = blockhash(block.number - 1); uint256 blockHashAsUint = uint256(blockHash); uint256 contractNonce = 0; function commit( string[] memory hopChains, string[] memory hopAssets, string[] memory hopAddresses, string memory dstChain, string memory dstAsset, string memory dstAddress, string memory srcAsset, address srcReceiver, uint timelock, address messenger ) external payable returns (bytes32 commitId) { if (msg.value == 0) { revert FundsNotSent(); } if (timelock <= block.timestamp) { revert NotFutureTimelock(); } contractNonce+=1; commitId = bytes32(blockHashAsUint ^ contractNonce); if (hasPHTLC(commitId)) { revert CommitIdAlreadyExists(); } commitIds.push(commitId); commits[commitId] = PHTLC( dstAddress, dstChain, dstAsset, srcAsset, payable(msg.sender), payable(srcReceiver), bytes32(0), timelock, msg.value, messenger, false, false ); emit TokenCommitted( commitId, hopChains, hopAssets, hopAddresses, dstChain, dstAddress, dstAsset, msg.sender, srcReceiver, srcAsset, msg.value, timelock, messenger ); } function uncommit(bytes32 commitId) external _committed(commitId) returns (bool) { PHTLC storage phtlc = commits[commitId]; if (phtlc.uncommitted) revert AlreadyUncommitted(); if (phtlc.locked) revert AlreadyLocked(); if (phtlc.timelock > block.timestamp) revert NotPassedTimelock(); phtlc.uncommitted = true; (bool success, ) = phtlc.sender.call{ value: phtlc.amount }(''); require(success, 'Transfer failed'); emit TokenUncommitted(commitId); return true; } function lockCommitment(bytes32 commitId, bytes32 hashlock, uint256 timelock) external _committed(commitId) returns (bytes32 lockId) { lockId = hashlock; if (commits[commitId].uncommitted == true) { revert AlreadyUncommitted(); } if (commits[commitId].locked == true) { revert AlreadyLocked(); } if (hasHTLC(lockId)) { revert LockAlreadyExists(); } if (msg.sender == commits[commitId].sender || msg.sender == commits[commitId].messenger) { commits[commitId].locked = true; commits[commitId].lockId = hashlock; locks[lockId] = HTLC( commits[commitId].dstAddress, commits[commitId].dstChain, commits[commitId].dstAsset, commits[commitId].srcAsset, payable(commits[commitId].sender), commits[commitId].srcReceiver, hashlock, 0x0, commits[commitId].amount, timelock, false, false ); lockIds.push(hashlock); emit TokenLocked( hashlock, commits[commitId].dstChain, commits[commitId].dstAddress, commits[commitId].dstAsset, commits[commitId].sender, commits[commitId].srcReceiver, commits[commitId].srcAsset, commits[commitId].amount, timelock, commits[commitId].messenger, commitId ); } else { revert NoAllowance(); } } function lock( bytes32 hashlock, uint256 timelock, address payable srcReceiver, string memory srcAsset, string memory dstChain, string memory dstAddress, string memory dstAsset, bytes32 commitId, address messenger ) external payable returns (bytes32 lockId) { if (msg.value == 0) { revert FundsNotSent(); } if (timelock <= block.timestamp) { revert NotFutureTimelock(); } if (hasHTLC(hashlock)) { revert LockAlreadyExists(); } locks[hashlock] = HTLC( dstAddress, dstChain, dstAsset, srcAsset, payable(msg.sender), srcReceiver, hashlock, 0x0, msg.value, timelock, false, false ); lockId = hashlock; lockIds.push(hashlock); commitIdToLockId[commitId] = lockId; emit TokenLocked( hashlock, dstChain, dstAddress, dstAsset, msg.sender, srcReceiver, srcAsset, msg.value, timelock, messenger, commitId ); if (messenger != address(0)) { uint256 codeSize; assembly { codeSize := extcodesize(messenger) } if (codeSize > 0) { try IMessenger(messenger).notify( commitId, hashlock, dstChain, dstAsset, dstAddress, srcAsset, payable(msg.sender), srcReceiver, msg.value, timelock, address(0) ) { // Notify successful } catch Error(string memory reason) { revert(reason); } catch (bytes memory lowLevelData) { emit LowLevelErrorOccurred(lowLevelData); revert('IMessenger notify failed'); } } else { revert NoMessenger(); } } } function redeem(bytes32 lockId, uint256 secret) external _locked(lockId) returns (bool) { HTLC storage htlc = locks[lockId]; if (htlc.hashlock != sha256(abi.encodePacked(secret))) revert HashlockNotMatch(); if (htlc.unlocked) revert AlreadyUnlocked(); if (htlc.redeemed) revert AlreadyRedeemed(); htlc.secret = secret; htlc.redeemed = true; (bool success, ) = htlc.srcReceiver.call{ value: htlc.amount }(''); require(success, 'Transfer failed'); emit TokenRedeemed(lockId, msg.sender); return true; } function unlock(bytes32 lockId) external _locked(lockId) returns (bool) { HTLC storage htlc = locks[lockId]; if (htlc.unlocked) revert AlreadyUnlocked(); if (htlc.redeemed) revert AlreadyRedeemed(); if (htlc.timelock > block.timestamp) revert NotPassedTimelock(); htlc.unlocked = true; (bool success, ) = htlc.sender.call{ value: htlc.amount }(''); require(success, 'Transfer failed'); emit TokenUnlocked(lockId); return true; } function getLockDetails(bytes32 lockId) public view returns (HTLC memory) { if (!hasHTLC(lockId)) { HTLC memory emptyHTLC = HTLC({ dstAddress: '', dstChain: '', dstAsset: '', srcAsset: '', sender: payable(address(0)), srcReceiver: payable(address(0)), hashlock: bytes32(0x0), secret: uint256(0), amount: uint256(0), timelock: uint256(0), redeemed: false, unlocked: false }); return emptyHTLC; } HTLC storage htlc = locks[lockId]; return htlc; } function getCommitDetails(bytes32 commitId) public view returns (PHTLC memory) { if (!hasPHTLC(commitId)) { PHTLC memory emptyPHTLC = PHTLC({ dstAddress: '', dstChain: '', dstAsset: '', srcAsset: '', sender: payable(address(0)), srcReceiver: payable(address(0)), lockId: bytes32(0), timelock: uint256(0), amount: uint256(0), messenger: address(0), locked: false, uncommitted: false }); return emptyPHTLC; } PHTLC storage phtlc = commits[commitId]; return phtlc; } function hasPHTLC(bytes32 commitId) internal view returns (bool exists) { exists = (commits[commitId].sender != address(0)); } function hasHTLC(bytes32 lockId) internal view returns (bool exists) { exists = (locks[lockId].sender != address(0)); } function getLocks(address senderAddr) public view returns (bytes32[] memory) { uint count = 0; for (uint i = 0; i < lockIds.length; i++) { HTLC memory htlc = locks[lockIds[i]]; if (htlc.sender == senderAddr) { count++; } } bytes32[] memory result = new bytes32[](count); uint j = 0; for (uint i = 0; i < lockIds.length; i++) { if (locks[lockIds[i]].sender == senderAddr) { result[j] = lockIds[i]; j++; } } return result; } function getCommits(address senderAddr) public view returns (bytes32[] memory) { uint count = 0; for (uint i = 0; i < commitIds.length; i++) { PHTLC memory phtlc = commits[commitIds[i]]; if (phtlc.sender == senderAddr) { count++; } } bytes32[] memory result = new bytes32[](count); uint j = 0; for (uint i = 0; i < commitIds.length; i++) { if (commits[commitIds[i]].sender == senderAddr) { result[j] = commitIds[i]; j++; } } return result; } function getLockIdByCommitId(bytes32 commitId) public view returns (bytes32) { return commitIdToLockId[commitId]; } }
Compiler Settings
{"viaIR":true,"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata"],"":["ast"]}},"optimizer":{"runs":200,"enabled":true},"libraries":{},"evmVersion":"paris"}
Contract ABI
[{"type":"error","name":"AlreadyLocked","inputs":[]},{"type":"error","name":"AlreadyRedeemed","inputs":[]},{"type":"error","name":"AlreadyUncommitted","inputs":[]},{"type":"error","name":"AlreadyUnlocked","inputs":[]},{"type":"error","name":"CommitIdAlreadyExists","inputs":[]},{"type":"error","name":"CommitmentNotExists","inputs":[]},{"type":"error","name":"FundsNotSent","inputs":[]},{"type":"error","name":"HashlockNotMatch","inputs":[]},{"type":"error","name":"LockAlreadyExists","inputs":[]},{"type":"error","name":"LockNotExists","inputs":[]},{"type":"error","name":"NoAllowance","inputs":[]},{"type":"error","name":"NoMessenger","inputs":[]},{"type":"error","name":"NotFutureTimelock","inputs":[]},{"type":"error","name":"NotPassedTimelock","inputs":[]},{"type":"event","name":"LowLevelErrorOccurred","inputs":[{"type":"bytes","name":"lowLevelData","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"TokenCommitted","inputs":[{"type":"bytes32","name":"commitId","internalType":"bytes32","indexed":false},{"type":"string[]","name":"hopChains","internalType":"string[]","indexed":false},{"type":"string[]","name":"hopAssets","internalType":"string[]","indexed":false},{"type":"string[]","name":"hopAddresses","internalType":"string[]","indexed":false},{"type":"string","name":"dstChain","internalType":"string","indexed":false},{"type":"string","name":"dstAddress","internalType":"string","indexed":false},{"type":"string","name":"dstAsset","internalType":"string","indexed":false},{"type":"address","name":"sender","internalType":"address","indexed":false},{"type":"address","name":"srcReceiver","internalType":"address","indexed":false},{"type":"string","name":"srcAsset","internalType":"string","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"timelock","internalType":"uint256","indexed":false},{"type":"address","name":"messenger","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"TokenLocked","inputs":[{"type":"bytes32","name":"hashlock","internalType":"bytes32","indexed":true},{"type":"string","name":"dstChain","internalType":"string","indexed":false},{"type":"string","name":"dstAddress","internalType":"string","indexed":false},{"type":"string","name":"dstAsset","internalType":"string","indexed":false},{"type":"address","name":"sender","internalType":"address","indexed":true},{"type":"address","name":"srcReceiver","internalType":"address","indexed":true},{"type":"string","name":"srcAsset","internalType":"string","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"timelock","internalType":"uint256","indexed":false},{"type":"address","name":"messenger","internalType":"address","indexed":false},{"type":"bytes32","name":"commitId","internalType":"bytes32","indexed":false}],"anonymous":false},{"type":"event","name":"TokenRedeemed","inputs":[{"type":"bytes32","name":"lockId","internalType":"bytes32","indexed":true},{"type":"address","name":"redeemAddress","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"TokenUncommitted","inputs":[{"type":"bytes32","name":"commitId","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"TokenUnlocked","inputs":[{"type":"bytes32","name":"lockId","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"payable","outputs":[{"type":"bytes32","name":"commitId","internalType":"bytes32"}],"name":"commit","inputs":[{"type":"string[]","name":"hopChains","internalType":"string[]"},{"type":"string[]","name":"hopAssets","internalType":"string[]"},{"type":"string[]","name":"hopAddresses","internalType":"string[]"},{"type":"string","name":"dstChain","internalType":"string"},{"type":"string","name":"dstAsset","internalType":"string"},{"type":"string","name":"dstAddress","internalType":"string"},{"type":"string","name":"srcAsset","internalType":"string"},{"type":"address","name":"srcReceiver","internalType":"address"},{"type":"uint256","name":"timelock","internalType":"uint256"},{"type":"address","name":"messenger","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct HashedTimeLockEther.PHTLC","components":[{"type":"string","name":"dstAddress","internalType":"string"},{"type":"string","name":"dstChain","internalType":"string"},{"type":"string","name":"dstAsset","internalType":"string"},{"type":"string","name":"srcAsset","internalType":"string"},{"type":"address","name":"sender","internalType":"address payable"},{"type":"address","name":"srcReceiver","internalType":"address payable"},{"type":"bytes32","name":"lockId","internalType":"bytes32"},{"type":"uint256","name":"timelock","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"address","name":"messenger","internalType":"address"},{"type":"bool","name":"locked","internalType":"bool"},{"type":"bool","name":"uncommitted","internalType":"bool"}]}],"name":"getCommitDetails","inputs":[{"type":"bytes32","name":"commitId","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32[]","name":"","internalType":"bytes32[]"}],"name":"getCommits","inputs":[{"type":"address","name":"senderAddr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct HashedTimeLockEther.HTLC","components":[{"type":"string","name":"dstAddress","internalType":"string"},{"type":"string","name":"dstChain","internalType":"string"},{"type":"string","name":"dstAsset","internalType":"string"},{"type":"string","name":"srcAsset","internalType":"string"},{"type":"address","name":"sender","internalType":"address payable"},{"type":"address","name":"srcReceiver","internalType":"address payable"},{"type":"bytes32","name":"hashlock","internalType":"bytes32"},{"type":"uint256","name":"secret","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"timelock","internalType":"uint256"},{"type":"bool","name":"redeemed","internalType":"bool"},{"type":"bool","name":"unlocked","internalType":"bool"}]}],"name":"getLockDetails","inputs":[{"type":"bytes32","name":"lockId","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getLockIdByCommitId","inputs":[{"type":"bytes32","name":"commitId","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32[]","name":"","internalType":"bytes32[]"}],"name":"getLocks","inputs":[{"type":"address","name":"senderAddr","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"bytes32","name":"lockId","internalType":"bytes32"}],"name":"lock","inputs":[{"type":"bytes32","name":"hashlock","internalType":"bytes32"},{"type":"uint256","name":"timelock","internalType":"uint256"},{"type":"address","name":"srcReceiver","internalType":"address payable"},{"type":"string","name":"srcAsset","internalType":"string"},{"type":"string","name":"dstChain","internalType":"string"},{"type":"string","name":"dstAddress","internalType":"string"},{"type":"string","name":"dstAsset","internalType":"string"},{"type":"bytes32","name":"commitId","internalType":"bytes32"},{"type":"address","name":"messenger","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"lockId","internalType":"bytes32"}],"name":"lockCommitment","inputs":[{"type":"bytes32","name":"commitId","internalType":"bytes32"},{"type":"bytes32","name":"hashlock","internalType":"bytes32"},{"type":"uint256","name":"timelock","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"redeem","inputs":[{"type":"bytes32","name":"lockId","internalType":"bytes32"},{"type":"uint256","name":"secret","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"uncommit","inputs":[{"type":"bytes32","name":"commitId","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"unlock","inputs":[{"type":"bytes32","name":"lockId","internalType":"bytes32"}]}]
Contract Creation Code
0x6080806040523461004557600019430143811161002f5740806005556006556000600755612bcb908161004b8239f35b634e487b7160e01b600052601160045260246000fd5b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c8063255f3154146122e75780632ea3b73c1461212357806339e35271146120f95780633b9c1f5b14612004578063673da15414611eac578063719f308914611cec578063c5bea8b514611539578063da76bb3814610bb3578063def94407146102ca578063ec9b5b3a146101c15763f5a1862a1461009657600080fd5b346101be5760203660031901126101be57600435906100cd82600052600160205260018060a01b0360046040600020015416151590565b156101ac578181526001602052604081209160098301805460ff8160a81c1661019a5760ff8160a01c1661018857600785015442106101765760ff60a81b1916600160a81b1790556004830154600890930154602093610149918491829182918291906001600160a01b03165af1610143612a33565b50612a63565b7fa123e15752679aa06522e49c50e26d336ea83e1aa2e8ecdc4a32f437a474d1366040519280a260018152f35b60405163b3f711f760e01b8152600490fd5b6040516317c3335f60e21b8152600490fd5b604051630e4a482d60e11b8152600490fd5b604051630bfa77dd60e41b8152600490fd5b80fd5b50346101be5760203660031901126101be57600435906101f982600052600060205260018060a01b0360046040600020015416151590565b156102b857818152806020526040812091600a8301805460ff8160081c166102a65760ff811661029457600985015442106101765761ff0019166101001790556004830154600890930154602093610267918491829182918291906001600160a01b03165af1610143612a33565b7f3d4cedda486476ed25b0bd452211f1c4b1af03b25ad9d223a96238f84ce640f46040519280a260018152f35b6040516306d3830f60e21b8152600490fd5b6040516328486b6360e11b8152600490fd5b604051632254ea3d60e11b8152600490fd5b506101403660031901126101be576004356001600160401b038111610baf576102f79036906004016124fc565b6024356001600160401b038111610bab576103169036906004016124fc565b906044356001600160401b038111610ba7576103369036906004016124fc565b6064356001600160401b038111610ba35761035590369060040161249e565b6084356001600160401b038111610b9f5761037490369060040161249e565b9060a4356001600160401b038111610b9b5761039490369060040161249e565b9160c4356001600160401b038111610b97576103b490369060040161249e565b9260e435926001600160a01b0384168403610b925761012435956001600160a01b0387168703610b92573415610b805742610104351115610b6e5760075460018101809111610b5a57600781905560065418600081815260016020526040902060040154909a906001600160a01b0316610b4857600454600160401b811015610b325761046261044b8260018f940160045561283e565b819391549060031b91821b91600019901b19161790565b9055604051906104718261242b565b84825283602083015285604083015287606083015233608083015260018060a01b03871660a08301528060c08301526101043560e08301523461010083015260018060a01b03891661012083015280610140830152806101608301528b81526001602052604081209082518051906001600160401b0382116109915781906104f985546125d8565b601f8111610ae4575b50602090601f8311600114610a7b578492610a70575b50508160011b916000199060031b1c19161782555b60208301518051906001600160401b03821161099157819061055260018601546125d8565b601f8111610a1f575b50602090601f83116001146109b05784926109a5575b50508160011b916000199060031b1c19161760018301555b60408301518051906001600160401b0382116109915781906105ae60028601546125d8565b601f8111610940575b50602090601f83116001146108d15784926108c6575b50508160011b916000199060031b1c19161760028301555b6060830151908151916001600160401b0383116108b25790829161060c60038601546125d8565b601f811161085c575b50602091601f84116001146107ed57926107e2575b50508160011b916000199060031b1c19161760038201555b60048101600160a01b60019003608084015116906001600160601b0360a01b91828254161790556005820190600160a01b6001900360a0850151169082541617905560c0820151600682015560e08201516007820155610100820151600882015560090190600160a01b60019003610120820151169082549160ff60a01b610140830151151560a01b169160ff60a81b906101600151151560a81b169269ffffffffffffffffffff60b01b1617171790556040519889986101a08c8b528060208c01528a0161071091612b38565b89810360408b015261072191612b38565b88810360608a015261073291612b38565b8781036080890152610743916123b4565b86810360a0880152610754916123b4565b85810360c0870152610765916123b4565b3360e08601526001600160a01b0390911661010085015283810361012085015261078e916123b4565b34610140840152610104356101608401526001600160a01b039091166101808301527f625ba51e51c5f2c394db4494f428998d9a34cd2f81e1ff9f134570a67f92ac469291900390a1604051908152602090f35b01519050388061062a565b6003860181526020812090945091905b601f1984168510610841576001945083601f19811610610828575b505050811b016003820155610642565b015160001960f88460031b161c19169055388080610818565b818101518355602094850194600190930192909101906107fd565b9091925060038501835260208320601f850160051c810191602086106108a8575b90601f86959493920160051c01905b8181106108995750610615565b6000815585945060010161088c565b909150819061087d565b634e487b7160e01b82526041600452602482fd5b0151905038806105cd565b9250600285018452602084209084935b601f1984168510610925576001945083601f1981161061090c575b505050811b0160028301556105e5565b015160001960f88460031b161c191690553880806108fc565b818101518355602094850194600190930192909101906108e1565b90915060028501845260208420601f840160051c81016020851061098a575b90849392915b601f830160051c8201811061097b5750506105b7565b60008155859450600101610965565b508061095f565b634e487b7160e01b83526041600452602483fd5b015190503880610571565b9250600185018452602084209084935b601f1984168510610a04576001945083601f198116106109eb575b505050811b016001830155610589565b015160001960f88460031b161c191690553880806109db565b818101518355602094850194600190930192909101906109c0565b90915060018501845260208420601f840160051c810160208510610a69575b90849392915b601f830160051c82018110610a5a57505061055b565b60008155859450600101610a44565b5080610a3e565b015190503880610518565b9250848452602084209084935b601f1984168510610ac9576001945083601f19811610610ab0575b505050811b01825561052d565b015160001960f88460031b161c19169055388080610aa3565b81810151835560209485019460019093019290910190610a88565b90915084845260208420601f840160051c810160208510610b2b575b90849392915b601f830160051c82018110610b1c575050610502565b60008155859450600101610b06565b5080610b00565b634e487b7160e01b600052604160045260246000fd5b604051637870919b60e01b8152600490fd5b634e487b7160e01b8b52601160045260248bfd5b604051633dd8280960e21b8152600490fd5b604051636f8ab38d60e11b8152600490fd5b600080fd5b8780fd5b8680fd5b8580fd5b8480fd5b8380fd5b8280fd5b5080fd5b506101203660031901126101be57604435906001600160a01b03821682036101be576064356001600160401b038111610baf57610bf490369060040161249e565b916084356001600160401b038111610bab57610c1490369060040161249e565b9060a4356001600160401b038111610ba757610c3490369060040161249e565b9360c4356001600160401b038111610ba357610c5490369060040161249e565b94610104356001600160a01b0381169003610ba3573415610b8057426024351115610b6e5760048035600090815260208190526040902001546001600160a01b031661152757604051610ca68161242b565b81815284602082015286604082015282606082015233608082015260018060a01b03841660a082015260043560c08201528560e08201523461010082015260243561012082015285610140820152856101608201526004358652856020526040862081518051906001600160401b0382116112be578190610d2784546125d8565b601f81116114da575b50602090601f8311600114611471578a92611466575b50508160011b916000199060031b1c19161781555b60208201518051906001600160401b0382116112be578190610d8060018501546125d8565b601f8111611416575b50602090601f83116001146113a7578a9261139c575b50508160011b916000199060031b1c19161760018201555b60408201518051906001600160401b0382116112be578190610ddc60028501546125d8565b601f811161134c575b50602090601f83116001146112dd578a926112d2575b50508160011b916000199060031b1c19161760028201555b60608201518051906001600160401b0382116112be57610e3660038401546125d8565b601f811161127a575b50602090601f831160011461120357928261016093600a93610f1a97968d926111f8575b50508160011b916000199060031b1c19161760038201555b6004810160018060a01b03608086015116906001600160601b0360a01b9182825416179055600582019060018060a01b0360a0870151169082541617905560c0840151600682015560e08401516007820155610100840151600882015561012084015160098201550191610f026101408201511515849060ff801983541691151516179055565b0151815461ff00191690151560081b61ff0016179055565b610f25600435612aa1565b60e4358552600260205260043560408620556040516101008152610f80610f72610f64610f566101008501896123b4565b8481036020860152856123b4565b8381036040850152896123b4565b8281036060840152846123b4565b34608083015260243560a08301526001600160a01b0361010435811660c084015260e43560e08401528516913391600435917f24804913990b29b6ec6950b6dce63c2cd286bae5e010ee05cbdeaacc09281d5c9181900390a4610104356001600160a01b0316610ff7575b60206040516004358152f35b610104353b156111e657610104356001600160a01b03163b15610ba3579161109085949261107e61105a9561106c6040519a8b988998635e863a5b60e01b8a5260e43560048b015260043560248b015261016060448b01526101648a01906123b4565b8881036003190160648a0152906123b4565b868103600319016084880152906123b4565b8481036003190160a4860152906123b4565b903360c484015260018060a01b031660e4830152346101048301526024356101248301528361014483015203818360018060a01b0361010435165af191826111cf575b50906111c3578060033d116111b2575b506308c379a014611177575b7f7b5bdb2f87e8e20f082bba9be5f7e870728f9bba18540559ccdcdcbb1fc5a08761112f61111b612a33565b6040519182916020835260208301906123b4565b0390a160405162461bcd60e51b815260206004820152601860248201527f494d657373656e676572206e6f74696679206661696c656400000000000000006044820152606490fd5b61117f612ac7565b8061118a57506110ef565b60405162461bcd60e51b8152602060048201529081906111ae9060248301906123b4565b0390fd5b9050600481803e5160e01c386110e3565b50388080808080610feb565b6001600160401b0381116108b257604052386110d3565b604051633127e9d760e11b8152600490fd5b015190503880610e63565b90600384018a5260208a20918a5b601f1985168110611262575083600a93610f1a97969360019361016097601f19811610611249575b505050811b016003820155610e7b565b015160001960f88460031b161c19169055388080611239565b91926020600181928685015181550194019201611211565b600384018a5260208a20601f840160051c8101602085106112b7575b601f830160051c820181106112ac575050610e3f565b8b8155600101611296565b5080611296565b634e487b7160e01b89526041600452602489fd5b015190503880610dfb565b9250600284018a5260208a20908a935b601f1984168510611331576001945083601f19811610611318575b505050811b016002820155610e13565b015160001960f88460031b161c19169055388080611308565b818101518355602094850194600190930192909101906112ed565b909150600284018a5260208a20601f840160051c810160208510611395575b90849392915b601f830160051c82018110611387575050610de5565b8c8155859450600101611371565b508061136b565b015190503880610d9f565b9250600184018a5260208a20908a935b601f19841685106113fb576001945083601f198116106113e2575b505050811b016001820155610db7565b015160001960f88460031b161c191690553880806113d2565b818101518355602094850194600190930192909101906113b7565b909150600184018a5260208a20601f840160051c81016020851061145f575b90849392915b601f830160051c82018110611451575050610d89565b8c815585945060010161143b565b5080611435565b015190503880610d46565b9250838a5260208a20908a935b601f19841685106114bf576001945083601f198116106114a6575b505050811b018155610d5b565b015160001960f88460031b161c19169055388080611499565b8181015183556020948501946001909301929091019061147e565b909150838a5260208a20601f840160051c810160208510611520575b90849392915b601f830160051c82018110611512575050610d30565b8c81558594506001016114fc565b50806114f6565b60405163748d150960e01b8152600490fd5b50346101be5760603660031901126101be5760048035600090815260016020526040902001546001600160a01b0316156101ac5760043581526001602052600160ff600960408420015460a81c1615151461019a5760043581526001602052600160ff600960408420015460a01c16151514610188576024356000908152602081905260409020600401546001600160a01b031661152757600435815260016020526040812060018060a01b036004820154163314908115611cd5575b5015611cc3576004803582526001602052604080832060098101805460ff60a01b1916600160a01b17905560243560068201559182015460058301546008840154925194936001600160a01b0391821692909116906003906116b79061165b8861242b565b6040516116738161166c8185612612565b0382612462565b88526040516116898161166c8160018601612612565b60208901526040516116a28161166c8160028601612612565b604089015261166c6040518094819301612612565b6060860152608085015260a084015260243560c08401528160e08401526101008301526044356101208301528061014083015280610160830152602435815280602052604081209180519283516001600160401b038111611a875761171c82546125d8565b601f8111611c82575b506020601f8211600114611c1c5784958293949592611c11575b50508160011b916000199060031b1c19161781555b60208201519283516001600160401b0381116108b25761177760018401546125d8565b601f8111611bcd575b506020601f8211600114611b615782939495829392611b56575b50508160011b916000199060031b1c19161760018301555b60408301519283516001600160401b038111610991576117d560028501546125d8565b601f8111611b12575b506020601f8211600114611aa65783949582939492611a9b575b50508160011b916000199060031b1c19161760028401555b60608101519283516001600160401b038111611a875761183360038301546125d8565b601f8111611a43575b506020601f82116001146119e5576118fe93928261016093600a9360409989926111f85750508160011b916000199060031b1c19161760038201556004810160018060a01b03608086015116906001600160601b0360a01b9182825416179055600582019060018060a01b0360a0870151169082541617905560c0840151600682015560e08401516007820155610100840151600882015561012084015160098201550191610f026101408201511515849060ff801983541691151516179055565b611909602435612aa1565b600435815260016020522060018060a01b0360048201541660018060a01b03600583015416917f24804913990b29b6ec6950b6dce63c2cd286bae5e010ee05cbdeaacc09281d5c60088201549160018060a01b036009820154166119b660405192610100845260036119a7611996611988610100880160018601612612565b878103602089015284612612565b868103604088015260028401612612565b91858303606087015201612612565b93608083015260443560a083015260c082015260043560e082015280602435930390a460206040516024358152f35b6003830185526020852095855b601f1984168110611a2b575092600183604098600a946118fe989761016097601f1981161061124957505050811b016003820155610e7b565b828201518855600190970196602092830192016119f2565b60038301855260208520601f830160051c810160208410611a80575b601f830160051c82018110611a7557505061183c565b868155600101611a5f565b5080611a5f565b634e487b7160e01b84526041600452602484fd5b0151905038806117f8565b6002850184526020842090845b601f1984168110611afa575060019394959683601f19811610611ae1575b505050811b016002840155611810565b015160001960f88460031b161c19169055388080611ad1565b9091602060018192858b015181550193019101611ab3565b60028501845260208420601f830160051c810160208410611b4f575b601f830160051c82018110611b445750506117de565b858155600101611b2e565b5080611b2e565b01519050388061179a565b6001840183526020832090835b601f1984168110611bb5575060019394959683601f19811610611b9c575b505050811b0160018301556117b2565b015160001960f88460031b161c19169055388080611b8c565b9091602060018192858b015181550193019101611b6e565b60018401835260208320601f830160051c810160208410611c0a575b601f830160051c82018110611bff575050611780565b848155600101611be9565b5080611be9565b01519050388061173f565b8285526020852090855b601f1984168110611c6a575060019394959683601f19811610611c51575b505050811b018155611754565b015160001960f88460031b161c19169055388080611c44565b9091602060018192858b015181550193019101611c26565b82855260208520601f830160051c810160208410611cbc575b601f830160051c82018110611cb1575050611725565b868155600101611c9b565b5080611c9b565b604051631d7eb35960e31b8152600490fd5b600901546001600160a01b031633149050386115f6565b50346101be57602080600319360112610baf57611d076123d9565b600380549290916001600160a01b039081169085805b868110611da75750611d2e906128e7565b958093815b878110611d4c5760405180611d488b826123ef565b0390f35b611d558161288b565b905490881b1c8352828252848460046040862001541614611d79575b600101611d33565b94611d9f600191611d898861288b565b9054908a1b1c611d99828d612919565b526128c2565b959050611d71565b611db08161288b565b905490871b1c88528785528360408920604051611dcc8161242b565b604051611ddd8161166c8186612612565b8152604051611df38161166c8160018701612612565b88820152604051611e0b8161166c8160028701612612565b6040820152604051611e238161166c818d8701612612565b606082015261016086600484015416928360808401528760058201541660a0840152600681015460c0840152600781015460e0840152600a600891828101546101008601526009810154610120860152015460ff9182821615156101408601521c16151591015214611e98575b600101611d1d565b90611ea46001916128c2565b919050611e90565b50346101be5760403660031901126101be57600435602435611ee682600052600060205260018060a01b0360046040600020015416151590565b156102b857818352602092808452604081209160068301546040518681019083825287815260408101918183106001600160401b03841117611ff05791859181611f398b95826040528351928391612391565b8101039060025afa15611fe557825103611fd357600a830190815460ff8160081c166102a65760ff811661029457600785019190915560ff191660011790556005820154600890920154611fa192829182918291906001600160a01b03165af1610143612a33565b7f0f7c50d316885e5d3719752f760bbbbf7d56363501e721eea4d913e255b632e482604051338152a260405160018152f35b60405163e73bcb3560e01b8152600490fd5b6040513d84823e3d90fd5b634e487b7160e01b86526041600452602486fd5b50346101be5760203660031901126101be5761202160043561292d565b604051809160208252805161208f612047610180928360208701526101a08601906123b4565b61207a612066602086015192601f1993848983030160408a01526123b4565b6040860151838883030160608901526123b4565b906060850151908683030160808701526123b4565b91608081015160018060a01b0380911660a08601528060a08301511660c086015260c082015160e086015260e08201516101009081870152820151610120908187015282015190610140911681860152810151906101609115158286015201511515908301520390f35b50346101be5760203660031901126101be5760406020916004358152600283522054604051908152f35b50346101be5760209060206003193601126101be576121406123d9565b6004546001600160a01b039390929091841681805b8581106121d75750612166906128e7565b9482805b86811061217f5760405180611d488a826123ef565b6121888161283e565b9054600391821b1c8352600187528484600460408620015416146121b0575b5060010161216a565b81956121d0916121c160019461283e565b9054911b1c611d99828c612919565b94906121a7565b826121e18261283e565b9054600391821b1c8652600180885261166c61225a604089209361166c61222f6040519561220e8761242b565b60405161221f8161166c818c612612565b8752604051928380928a01612612565b8b8501526040516122478161166c8160028a01612612565b6040850152604051928380928701612612565b60608201526101608a6004840154169283608084015260098c6005830154169160a09283860152600681015460c0860152600781015460e08601526008810154610100860152015480918d821661012086015260ff9283911c16151561014085015260a81c161515910152146122d3575b600101612155565b906122df6001916128c2565b9190506122cb565b50346101be5760203660031901126101be576123046004356126a8565b604051809160208252805161232a612047610180928360208701526101a08601906123b4565b91608081015160018060a01b0380911660a086015260a08201511660c085015260c081015160e085015260e0810151610100908186015281015161012090818601528101516101409081860152810151906101609115158286015201511515908301520390f35b60005b8381106123a45750506000910152565b8181015183820152602001612394565b906020916123cd81518092818552858086019101612391565b601f01601f1916010190565b600435906001600160a01b0382168203610b9257565b602090602060408183019282815285518094520193019160005b828110612417575050505090565b835185529381019392810192600101612409565b61018081019081106001600160401b03821117610b3257604052565b602081019081106001600160401b03821117610b3257604052565b90601f801991011681019081106001600160401b03821117610b3257604052565b6001600160401b038111610b3257601f01601f191660200190565b81601f82011215610b92578035906124b582612483565b926124c36040519485612462565b82845260208383010111610b9257816000926020809301838601378301015290565b6001600160401b038111610b325760051b60200190565b81601f82011215610b9257803591602091612516846124e5565b936125246040519586612462565b808552838086019160051b83010192808411610b9257848301915b84831061254f5750505050505090565b82356001600160401b038111610b925786916125708484809489010161249e565b81520192019161253f565b604051906125888261242b565b816060815260606020820152606060408201526060808201526101606000918260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201520152565b90600182811c92168015612608575b60208310146125f257565b634e487b7160e01b600052602260045260246000fd5b91607f16916125e7565b805460009392612621826125d8565b918282526020936001916001811690816000146126895750600114612648575b5050505050565b90939495506000929192528360002092846000945b83861061267557505050500101903880808080612641565b80548587018301529401938590820161265d565b60ff19168685015250505090151560051b010191503880808080612641565b6126b061257b565b506000818152602081905260409020600401546001600160a01b0316156127ae576000526000602052604060ff600a826000208351936126ef8561242b565b80516126ff8161166c8186612612565b855280516127148161166c8160018701612612565b6020860152805161272c8161166c8160028701612612565b81860152516127428161166c8160038601612612565b606085015260048101546001600160a01b03908116608086015260058201541660a0850152600681015460c0850152600781015460e085015260088082015461010086015260098201546101208601529101548281161515610140850152901c16151561016082015290565b5060408051906127bd8261242b565b8051906127c982612447565b600091828152835280516127dc81612447565b828152602084015280516127ef81612447565b828152818401525161280081612447565b81815260608301528060808301528060a08301528060c08301528060e083015280610100830152806101208301528061014083015261016082015290565b6004548110156128755760046000527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0190600090565b634e487b7160e01b600052603260045260246000fd5b6003548110156128755760036000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0190600090565b60001981146128d15760010190565b634e487b7160e01b600052601160045260246000fd5b906128f1826124e5565b6128fe6040519182612462565b828152809261290f601f19916124e5565b0190602036910137565b80518210156128755760209160051b010190565b61293561257b565b506000818152600160205260409020600401546001600160a01b0316156127ae576000526001602052604060ff816000208251926129728461242b565b80516129828161166c8186612612565b845280516129978161166c8160018701612612565b602085015280516129af8161166c8160028701612612565b81850152516129c58161166c8160038601612612565b6060840152600960018060a01b03918260048201541660808601528260058201541660a0860152600681015460c0860152600781015460e086015260088101546101008601520154908116610120840152818160a01c16151561014084015260a81c16151561016082015290565b3d15612a5e573d90612a4482612483565b91612a526040519384612462565b82523d6000602084013e565b606090565b15612a6a57565b60405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606490fd5b600354600160401b811015610b325761044b816001612ac3930160035561288b565b9055565b600060443d10612b2457604051600319913d83016004833e81516001600160401b03918282113d602484011117612b2757818401948551938411612b2f573d85010160208487010111612b275750612b2492910160200190612462565b90565b949350505050565b50949350505050565b90808251908181526020809101926020808460051b8301019501936000915b848310612b675750505050505090565b9091929394958480612b85600193601f198682030187528a516123b4565b9801930193019194939290612b5756fea2646970667358221220b4a9d8f0a50b1eed6d62bcd563d06b62e9fe741f6099eec940d696fb87f75c1464736f6c63430008170033
Deployed ByteCode
0x6080604052600436101561001257600080fd5b6000803560e01c8063255f3154146122e75780632ea3b73c1461212357806339e35271146120f95780633b9c1f5b14612004578063673da15414611eac578063719f308914611cec578063c5bea8b514611539578063da76bb3814610bb3578063def94407146102ca578063ec9b5b3a146101c15763f5a1862a1461009657600080fd5b346101be5760203660031901126101be57600435906100cd82600052600160205260018060a01b0360046040600020015416151590565b156101ac578181526001602052604081209160098301805460ff8160a81c1661019a5760ff8160a01c1661018857600785015442106101765760ff60a81b1916600160a81b1790556004830154600890930154602093610149918491829182918291906001600160a01b03165af1610143612a33565b50612a63565b7fa123e15752679aa06522e49c50e26d336ea83e1aa2e8ecdc4a32f437a474d1366040519280a260018152f35b60405163b3f711f760e01b8152600490fd5b6040516317c3335f60e21b8152600490fd5b604051630e4a482d60e11b8152600490fd5b604051630bfa77dd60e41b8152600490fd5b80fd5b50346101be5760203660031901126101be57600435906101f982600052600060205260018060a01b0360046040600020015416151590565b156102b857818152806020526040812091600a8301805460ff8160081c166102a65760ff811661029457600985015442106101765761ff0019166101001790556004830154600890930154602093610267918491829182918291906001600160a01b03165af1610143612a33565b7f3d4cedda486476ed25b0bd452211f1c4b1af03b25ad9d223a96238f84ce640f46040519280a260018152f35b6040516306d3830f60e21b8152600490fd5b6040516328486b6360e11b8152600490fd5b604051632254ea3d60e11b8152600490fd5b506101403660031901126101be576004356001600160401b038111610baf576102f79036906004016124fc565b6024356001600160401b038111610bab576103169036906004016124fc565b906044356001600160401b038111610ba7576103369036906004016124fc565b6064356001600160401b038111610ba35761035590369060040161249e565b6084356001600160401b038111610b9f5761037490369060040161249e565b9060a4356001600160401b038111610b9b5761039490369060040161249e565b9160c4356001600160401b038111610b97576103b490369060040161249e565b9260e435926001600160a01b0384168403610b925761012435956001600160a01b0387168703610b92573415610b805742610104351115610b6e5760075460018101809111610b5a57600781905560065418600081815260016020526040902060040154909a906001600160a01b0316610b4857600454600160401b811015610b325761046261044b8260018f940160045561283e565b819391549060031b91821b91600019901b19161790565b9055604051906104718261242b565b84825283602083015285604083015287606083015233608083015260018060a01b03871660a08301528060c08301526101043560e08301523461010083015260018060a01b03891661012083015280610140830152806101608301528b81526001602052604081209082518051906001600160401b0382116109915781906104f985546125d8565b601f8111610ae4575b50602090601f8311600114610a7b578492610a70575b50508160011b916000199060031b1c19161782555b60208301518051906001600160401b03821161099157819061055260018601546125d8565b601f8111610a1f575b50602090601f83116001146109b05784926109a5575b50508160011b916000199060031b1c19161760018301555b60408301518051906001600160401b0382116109915781906105ae60028601546125d8565b601f8111610940575b50602090601f83116001146108d15784926108c6575b50508160011b916000199060031b1c19161760028301555b6060830151908151916001600160401b0383116108b25790829161060c60038601546125d8565b601f811161085c575b50602091601f84116001146107ed57926107e2575b50508160011b916000199060031b1c19161760038201555b60048101600160a01b60019003608084015116906001600160601b0360a01b91828254161790556005820190600160a01b6001900360a0850151169082541617905560c0820151600682015560e08201516007820155610100820151600882015560090190600160a01b60019003610120820151169082549160ff60a01b610140830151151560a01b169160ff60a81b906101600151151560a81b169269ffffffffffffffffffff60b01b1617171790556040519889986101a08c8b528060208c01528a0161071091612b38565b89810360408b015261072191612b38565b88810360608a015261073291612b38565b8781036080890152610743916123b4565b86810360a0880152610754916123b4565b85810360c0870152610765916123b4565b3360e08601526001600160a01b0390911661010085015283810361012085015261078e916123b4565b34610140840152610104356101608401526001600160a01b039091166101808301527f625ba51e51c5f2c394db4494f428998d9a34cd2f81e1ff9f134570a67f92ac469291900390a1604051908152602090f35b01519050388061062a565b6003860181526020812090945091905b601f1984168510610841576001945083601f19811610610828575b505050811b016003820155610642565b015160001960f88460031b161c19169055388080610818565b818101518355602094850194600190930192909101906107fd565b9091925060038501835260208320601f850160051c810191602086106108a8575b90601f86959493920160051c01905b8181106108995750610615565b6000815585945060010161088c565b909150819061087d565b634e487b7160e01b82526041600452602482fd5b0151905038806105cd565b9250600285018452602084209084935b601f1984168510610925576001945083601f1981161061090c575b505050811b0160028301556105e5565b015160001960f88460031b161c191690553880806108fc565b818101518355602094850194600190930192909101906108e1565b90915060028501845260208420601f840160051c81016020851061098a575b90849392915b601f830160051c8201811061097b5750506105b7565b60008155859450600101610965565b508061095f565b634e487b7160e01b83526041600452602483fd5b015190503880610571565b9250600185018452602084209084935b601f1984168510610a04576001945083601f198116106109eb575b505050811b016001830155610589565b015160001960f88460031b161c191690553880806109db565b818101518355602094850194600190930192909101906109c0565b90915060018501845260208420601f840160051c810160208510610a69575b90849392915b601f830160051c82018110610a5a57505061055b565b60008155859450600101610a44565b5080610a3e565b015190503880610518565b9250848452602084209084935b601f1984168510610ac9576001945083601f19811610610ab0575b505050811b01825561052d565b015160001960f88460031b161c19169055388080610aa3565b81810151835560209485019460019093019290910190610a88565b90915084845260208420601f840160051c810160208510610b2b575b90849392915b601f830160051c82018110610b1c575050610502565b60008155859450600101610b06565b5080610b00565b634e487b7160e01b600052604160045260246000fd5b604051637870919b60e01b8152600490fd5b634e487b7160e01b8b52601160045260248bfd5b604051633dd8280960e21b8152600490fd5b604051636f8ab38d60e11b8152600490fd5b600080fd5b8780fd5b8680fd5b8580fd5b8480fd5b8380fd5b8280fd5b5080fd5b506101203660031901126101be57604435906001600160a01b03821682036101be576064356001600160401b038111610baf57610bf490369060040161249e565b916084356001600160401b038111610bab57610c1490369060040161249e565b9060a4356001600160401b038111610ba757610c3490369060040161249e565b9360c4356001600160401b038111610ba357610c5490369060040161249e565b94610104356001600160a01b0381169003610ba3573415610b8057426024351115610b6e5760048035600090815260208190526040902001546001600160a01b031661152757604051610ca68161242b565b81815284602082015286604082015282606082015233608082015260018060a01b03841660a082015260043560c08201528560e08201523461010082015260243561012082015285610140820152856101608201526004358652856020526040862081518051906001600160401b0382116112be578190610d2784546125d8565b601f81116114da575b50602090601f8311600114611471578a92611466575b50508160011b916000199060031b1c19161781555b60208201518051906001600160401b0382116112be578190610d8060018501546125d8565b601f8111611416575b50602090601f83116001146113a7578a9261139c575b50508160011b916000199060031b1c19161760018201555b60408201518051906001600160401b0382116112be578190610ddc60028501546125d8565b601f811161134c575b50602090601f83116001146112dd578a926112d2575b50508160011b916000199060031b1c19161760028201555b60608201518051906001600160401b0382116112be57610e3660038401546125d8565b601f811161127a575b50602090601f831160011461120357928261016093600a93610f1a97968d926111f8575b50508160011b916000199060031b1c19161760038201555b6004810160018060a01b03608086015116906001600160601b0360a01b9182825416179055600582019060018060a01b0360a0870151169082541617905560c0840151600682015560e08401516007820155610100840151600882015561012084015160098201550191610f026101408201511515849060ff801983541691151516179055565b0151815461ff00191690151560081b61ff0016179055565b610f25600435612aa1565b60e4358552600260205260043560408620556040516101008152610f80610f72610f64610f566101008501896123b4565b8481036020860152856123b4565b8381036040850152896123b4565b8281036060840152846123b4565b34608083015260243560a08301526001600160a01b0361010435811660c084015260e43560e08401528516913391600435917f24804913990b29b6ec6950b6dce63c2cd286bae5e010ee05cbdeaacc09281d5c9181900390a4610104356001600160a01b0316610ff7575b60206040516004358152f35b610104353b156111e657610104356001600160a01b03163b15610ba3579161109085949261107e61105a9561106c6040519a8b988998635e863a5b60e01b8a5260e43560048b015260043560248b015261016060448b01526101648a01906123b4565b8881036003190160648a0152906123b4565b868103600319016084880152906123b4565b8481036003190160a4860152906123b4565b903360c484015260018060a01b031660e4830152346101048301526024356101248301528361014483015203818360018060a01b0361010435165af191826111cf575b50906111c3578060033d116111b2575b506308c379a014611177575b7f7b5bdb2f87e8e20f082bba9be5f7e870728f9bba18540559ccdcdcbb1fc5a08761112f61111b612a33565b6040519182916020835260208301906123b4565b0390a160405162461bcd60e51b815260206004820152601860248201527f494d657373656e676572206e6f74696679206661696c656400000000000000006044820152606490fd5b61117f612ac7565b8061118a57506110ef565b60405162461bcd60e51b8152602060048201529081906111ae9060248301906123b4565b0390fd5b9050600481803e5160e01c386110e3565b50388080808080610feb565b6001600160401b0381116108b257604052386110d3565b604051633127e9d760e11b8152600490fd5b015190503880610e63565b90600384018a5260208a20918a5b601f1985168110611262575083600a93610f1a97969360019361016097601f19811610611249575b505050811b016003820155610e7b565b015160001960f88460031b161c19169055388080611239565b91926020600181928685015181550194019201611211565b600384018a5260208a20601f840160051c8101602085106112b7575b601f830160051c820181106112ac575050610e3f565b8b8155600101611296565b5080611296565b634e487b7160e01b89526041600452602489fd5b015190503880610dfb565b9250600284018a5260208a20908a935b601f1984168510611331576001945083601f19811610611318575b505050811b016002820155610e13565b015160001960f88460031b161c19169055388080611308565b818101518355602094850194600190930192909101906112ed565b909150600284018a5260208a20601f840160051c810160208510611395575b90849392915b601f830160051c82018110611387575050610de5565b8c8155859450600101611371565b508061136b565b015190503880610d9f565b9250600184018a5260208a20908a935b601f19841685106113fb576001945083601f198116106113e2575b505050811b016001820155610db7565b015160001960f88460031b161c191690553880806113d2565b818101518355602094850194600190930192909101906113b7565b909150600184018a5260208a20601f840160051c81016020851061145f575b90849392915b601f830160051c82018110611451575050610d89565b8c815585945060010161143b565b5080611435565b015190503880610d46565b9250838a5260208a20908a935b601f19841685106114bf576001945083601f198116106114a6575b505050811b018155610d5b565b015160001960f88460031b161c19169055388080611499565b8181015183556020948501946001909301929091019061147e565b909150838a5260208a20601f840160051c810160208510611520575b90849392915b601f830160051c82018110611512575050610d30565b8c81558594506001016114fc565b50806114f6565b60405163748d150960e01b8152600490fd5b50346101be5760603660031901126101be5760048035600090815260016020526040902001546001600160a01b0316156101ac5760043581526001602052600160ff600960408420015460a81c1615151461019a5760043581526001602052600160ff600960408420015460a01c16151514610188576024356000908152602081905260409020600401546001600160a01b031661152757600435815260016020526040812060018060a01b036004820154163314908115611cd5575b5015611cc3576004803582526001602052604080832060098101805460ff60a01b1916600160a01b17905560243560068201559182015460058301546008840154925194936001600160a01b0391821692909116906003906116b79061165b8861242b565b6040516116738161166c8185612612565b0382612462565b88526040516116898161166c8160018601612612565b60208901526040516116a28161166c8160028601612612565b604089015261166c6040518094819301612612565b6060860152608085015260a084015260243560c08401528160e08401526101008301526044356101208301528061014083015280610160830152602435815280602052604081209180519283516001600160401b038111611a875761171c82546125d8565b601f8111611c82575b506020601f8211600114611c1c5784958293949592611c11575b50508160011b916000199060031b1c19161781555b60208201519283516001600160401b0381116108b25761177760018401546125d8565b601f8111611bcd575b506020601f8211600114611b615782939495829392611b56575b50508160011b916000199060031b1c19161760018301555b60408301519283516001600160401b038111610991576117d560028501546125d8565b601f8111611b12575b506020601f8211600114611aa65783949582939492611a9b575b50508160011b916000199060031b1c19161760028401555b60608101519283516001600160401b038111611a875761183360038301546125d8565b601f8111611a43575b506020601f82116001146119e5576118fe93928261016093600a9360409989926111f85750508160011b916000199060031b1c19161760038201556004810160018060a01b03608086015116906001600160601b0360a01b9182825416179055600582019060018060a01b0360a0870151169082541617905560c0840151600682015560e08401516007820155610100840151600882015561012084015160098201550191610f026101408201511515849060ff801983541691151516179055565b611909602435612aa1565b600435815260016020522060018060a01b0360048201541660018060a01b03600583015416917f24804913990b29b6ec6950b6dce63c2cd286bae5e010ee05cbdeaacc09281d5c60088201549160018060a01b036009820154166119b660405192610100845260036119a7611996611988610100880160018601612612565b878103602089015284612612565b868103604088015260028401612612565b91858303606087015201612612565b93608083015260443560a083015260c082015260043560e082015280602435930390a460206040516024358152f35b6003830185526020852095855b601f1984168110611a2b575092600183604098600a946118fe989761016097601f1981161061124957505050811b016003820155610e7b565b828201518855600190970196602092830192016119f2565b60038301855260208520601f830160051c810160208410611a80575b601f830160051c82018110611a7557505061183c565b868155600101611a5f565b5080611a5f565b634e487b7160e01b84526041600452602484fd5b0151905038806117f8565b6002850184526020842090845b601f1984168110611afa575060019394959683601f19811610611ae1575b505050811b016002840155611810565b015160001960f88460031b161c19169055388080611ad1565b9091602060018192858b015181550193019101611ab3565b60028501845260208420601f830160051c810160208410611b4f575b601f830160051c82018110611b445750506117de565b858155600101611b2e565b5080611b2e565b01519050388061179a565b6001840183526020832090835b601f1984168110611bb5575060019394959683601f19811610611b9c575b505050811b0160018301556117b2565b015160001960f88460031b161c19169055388080611b8c565b9091602060018192858b015181550193019101611b6e565b60018401835260208320601f830160051c810160208410611c0a575b601f830160051c82018110611bff575050611780565b848155600101611be9565b5080611be9565b01519050388061173f565b8285526020852090855b601f1984168110611c6a575060019394959683601f19811610611c51575b505050811b018155611754565b015160001960f88460031b161c19169055388080611c44565b9091602060018192858b015181550193019101611c26565b82855260208520601f830160051c810160208410611cbc575b601f830160051c82018110611cb1575050611725565b868155600101611c9b565b5080611c9b565b604051631d7eb35960e31b8152600490fd5b600901546001600160a01b031633149050386115f6565b50346101be57602080600319360112610baf57611d076123d9565b600380549290916001600160a01b039081169085805b868110611da75750611d2e906128e7565b958093815b878110611d4c5760405180611d488b826123ef565b0390f35b611d558161288b565b905490881b1c8352828252848460046040862001541614611d79575b600101611d33565b94611d9f600191611d898861288b565b9054908a1b1c611d99828d612919565b526128c2565b959050611d71565b611db08161288b565b905490871b1c88528785528360408920604051611dcc8161242b565b604051611ddd8161166c8186612612565b8152604051611df38161166c8160018701612612565b88820152604051611e0b8161166c8160028701612612565b6040820152604051611e238161166c818d8701612612565b606082015261016086600484015416928360808401528760058201541660a0840152600681015460c0840152600781015460e0840152600a600891828101546101008601526009810154610120860152015460ff9182821615156101408601521c16151591015214611e98575b600101611d1d565b90611ea46001916128c2565b919050611e90565b50346101be5760403660031901126101be57600435602435611ee682600052600060205260018060a01b0360046040600020015416151590565b156102b857818352602092808452604081209160068301546040518681019083825287815260408101918183106001600160401b03841117611ff05791859181611f398b95826040528351928391612391565b8101039060025afa15611fe557825103611fd357600a830190815460ff8160081c166102a65760ff811661029457600785019190915560ff191660011790556005820154600890920154611fa192829182918291906001600160a01b03165af1610143612a33565b7f0f7c50d316885e5d3719752f760bbbbf7d56363501e721eea4d913e255b632e482604051338152a260405160018152f35b60405163e73bcb3560e01b8152600490fd5b6040513d84823e3d90fd5b634e487b7160e01b86526041600452602486fd5b50346101be5760203660031901126101be5761202160043561292d565b604051809160208252805161208f612047610180928360208701526101a08601906123b4565b61207a612066602086015192601f1993848983030160408a01526123b4565b6040860151838883030160608901526123b4565b906060850151908683030160808701526123b4565b91608081015160018060a01b0380911660a08601528060a08301511660c086015260c082015160e086015260e08201516101009081870152820151610120908187015282015190610140911681860152810151906101609115158286015201511515908301520390f35b50346101be5760203660031901126101be5760406020916004358152600283522054604051908152f35b50346101be5760209060206003193601126101be576121406123d9565b6004546001600160a01b039390929091841681805b8581106121d75750612166906128e7565b9482805b86811061217f5760405180611d488a826123ef565b6121888161283e565b9054600391821b1c8352600187528484600460408620015416146121b0575b5060010161216a565b81956121d0916121c160019461283e565b9054911b1c611d99828c612919565b94906121a7565b826121e18261283e565b9054600391821b1c8652600180885261166c61225a604089209361166c61222f6040519561220e8761242b565b60405161221f8161166c818c612612565b8752604051928380928a01612612565b8b8501526040516122478161166c8160028a01612612565b6040850152604051928380928701612612565b60608201526101608a6004840154169283608084015260098c6005830154169160a09283860152600681015460c0860152600781015460e08601526008810154610100860152015480918d821661012086015260ff9283911c16151561014085015260a81c161515910152146122d3575b600101612155565b906122df6001916128c2565b9190506122cb565b50346101be5760203660031901126101be576123046004356126a8565b604051809160208252805161232a612047610180928360208701526101a08601906123b4565b91608081015160018060a01b0380911660a086015260a08201511660c085015260c081015160e085015260e0810151610100908186015281015161012090818601528101516101409081860152810151906101609115158286015201511515908301520390f35b60005b8381106123a45750506000910152565b8181015183820152602001612394565b906020916123cd81518092818552858086019101612391565b601f01601f1916010190565b600435906001600160a01b0382168203610b9257565b602090602060408183019282815285518094520193019160005b828110612417575050505090565b835185529381019392810192600101612409565b61018081019081106001600160401b03821117610b3257604052565b602081019081106001600160401b03821117610b3257604052565b90601f801991011681019081106001600160401b03821117610b3257604052565b6001600160401b038111610b3257601f01601f191660200190565b81601f82011215610b92578035906124b582612483565b926124c36040519485612462565b82845260208383010111610b9257816000926020809301838601378301015290565b6001600160401b038111610b325760051b60200190565b81601f82011215610b9257803591602091612516846124e5565b936125246040519586612462565b808552838086019160051b83010192808411610b9257848301915b84831061254f5750505050505090565b82356001600160401b038111610b925786916125708484809489010161249e565b81520192019161253f565b604051906125888261242b565b816060815260606020820152606060408201526060808201526101606000918260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201520152565b90600182811c92168015612608575b60208310146125f257565b634e487b7160e01b600052602260045260246000fd5b91607f16916125e7565b805460009392612621826125d8565b918282526020936001916001811690816000146126895750600114612648575b5050505050565b90939495506000929192528360002092846000945b83861061267557505050500101903880808080612641565b80548587018301529401938590820161265d565b60ff19168685015250505090151560051b010191503880808080612641565b6126b061257b565b506000818152602081905260409020600401546001600160a01b0316156127ae576000526000602052604060ff600a826000208351936126ef8561242b565b80516126ff8161166c8186612612565b855280516127148161166c8160018701612612565b6020860152805161272c8161166c8160028701612612565b81860152516127428161166c8160038601612612565b606085015260048101546001600160a01b03908116608086015260058201541660a0850152600681015460c0850152600781015460e085015260088082015461010086015260098201546101208601529101548281161515610140850152901c16151561016082015290565b5060408051906127bd8261242b565b8051906127c982612447565b600091828152835280516127dc81612447565b828152602084015280516127ef81612447565b828152818401525161280081612447565b81815260608301528060808301528060a08301528060c08301528060e083015280610100830152806101208301528061014083015261016082015290565b6004548110156128755760046000527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0190600090565b634e487b7160e01b600052603260045260246000fd5b6003548110156128755760036000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0190600090565b60001981146128d15760010190565b634e487b7160e01b600052601160045260246000fd5b906128f1826124e5565b6128fe6040519182612462565b828152809261290f601f19916124e5565b0190602036910137565b80518210156128755760209160051b010190565b61293561257b565b506000818152600160205260409020600401546001600160a01b0316156127ae576000526001602052604060ff816000208251926129728461242b565b80516129828161166c8186612612565b845280516129978161166c8160018701612612565b602085015280516129af8161166c8160028701612612565b81850152516129c58161166c8160038601612612565b6060840152600960018060a01b03918260048201541660808601528260058201541660a0860152600681015460c0860152600781015460e086015260088101546101008601520154908116610120840152818160a01c16151561014084015260a81c16151561016082015290565b3d15612a5e573d90612a4482612483565b91612a526040519384612462565b82523d6000602084013e565b606090565b15612a6a57565b60405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606490fd5b600354600160401b811015610b325761044b816001612ac3930160035561288b565b9055565b600060443d10612b2457604051600319913d83016004833e81516001600160401b03918282113d602484011117612b2757818401948551938411612b2f573d85010160208487010111612b275750612b2492910160200190612462565b90565b949350505050565b50949350505050565b90808251908181526020809101926020808460051b8301019501936000915b848310612b675750505050505090565b9091929394958480612b85600193601f198682030187528a516123b4565b9801930193019194939290612b5756fea2646970667358221220b4a9d8f0a50b1eed6d62bcd563d06b62e9fe741f6099eec940d696fb87f75c1464736f6c63430008170033