Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- LayerswapV8
- Optimization enabled
- true
- Compiler version
- v0.8.23+commit.f704f362
- Optimization runs
- 200
- EVM Version
- paris
- Verified at
- 2024-09-23T13:13:01.741160Z
contracts/HashedTimeLockEther.sol
/* _ __ _____ | | __ _ _ _ ___ _ __ _____ ____ _ _ __ \ \ / ( _ ) | | / _` | | | |/ _ \ '__/ __\ \ /\ / / _` | '_ \ \ \ / // _ \ | |__| (_| | |_| | __/ | \__ \\ V V / (_| | |_) | \ V /| (_) | |_____\__,_|\__, |\___|_| |___/ \_/\_/ \__,_| .__/ \_/ \___/ |___/ |_| */ // SPDX-License-Identifier: MIT pragma solidity 0.8.23; import '@openzeppelin/contracts/utils/cryptography/ECDSA.sol'; import '@openzeppelin/contracts/utils/Address.sol'; // Domain separator ensures signatures are unique to this contract and chain, preventing replay attacks. struct EIP712Domain { string name; string version; uint256 chainId; address verifyingContract; bytes32 salt; } // Interface for Messenger, to be notified when LP locks funds, with this address specified as the messenger. interface IMessenger { function notify( bytes32 Id, 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 LayerswapV8 { using ECDSA for bytes32; using Address for address; bytes32 private DOMAIN_SEPARATOR; bytes32 private constant SALT = keccak256(abi.encodePacked('Layerswap V8')); constructor() { DOMAIN_SEPARATOR = hashDomain( EIP712Domain({ name: 'LayerswapV8', version: '1', chainId: block.chainid, verifyingContract: address(this), salt: SALT }) ); } error FundsNotSent(); error NotFutureTimelock(); error NotPassedTimelock(); error LockAlreadyExists(); error HTLCAlreadyExists(); error HTLCNotExists(); error HashlockNotMatch(); error AlreadyRedeemed(); error AlreadyRefunded(); error NoMessenger(); error AlreadyLocked(); error NoAllowance(); error InvalidSigniture(); error HashlockAlreadySet(); // Structure for storing swap-related data struct HTLC { string dstAddress; string dstChain; string dstAsset; string srcAsset; address payable sender; address payable srcReceiver; bytes32 hashlock; uint256 timelock; uint256 amount; uint256 secret; address messenger; bool redeemed; bool refunded; } struct addLockMsg { bytes32 Id; bytes32 hashlock; uint256 timelock; } event TokenCommitted( bytes32 indexed Id, string[] hopChains, string[] hopAssets, string[] hopAddresses, string dstChain, string dstAddress, string dstAsset, address indexed sender, address indexed srcReceiver, string srcAsset, uint256 amount, uint256 timelock, address messenger ); event TokenLocked( bytes32 indexed Id, bytes32 hashlock, string dstChain, string dstAddress, string dstAsset, address indexed sender, address indexed srcReceiver, string srcAsset, uint256 amount, uint256 timelock, address messenger ); event TokenLockAdded(bytes32 indexed Id, address messenger, bytes32 hashlock, uint256 timelock); event TokenRefunded(bytes32 indexed Id); event TokenRedeemed(bytes32 indexed Id, address redeemAddress); event LowLevelErrorOccurred(bytes lowLevelData); modifier _exists(bytes32 Id) { if (!hasHTLC(Id)) revert HTLCNotExists(); _; } mapping(bytes32 => HTLC) contracts; bytes32[] contractIds; uint256 blockHashAsUint = uint256(blockhash(block.number - 1)); 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, uint256 timelock, address messenger ) external payable returns (bytes32 Id) { if (msg.value == 0) { revert FundsNotSent(); } if (timelock <= block.timestamp) { revert NotFutureTimelock(); } contractNonce += 1; Id = bytes32(blockHashAsUint ^ contractNonce); //Remove this check; the ID is guaranteed to be unique. if (hasHTLC(Id)) { revert HTLCAlreadyExists(); } contractIds.push(Id); contracts[Id] = HTLC( dstAddress, dstChain, dstAsset, srcAsset, payable(msg.sender), payable(srcReceiver), bytes32(0), timelock, msg.value, uint256(0), messenger, false, false ); emit TokenCommitted( Id, hopChains, hopAssets, hopAddresses, dstChain, dstAddress, dstAsset, msg.sender, srcReceiver, srcAsset, msg.value, timelock, messenger ); } function refund(bytes32 Id) external _exists(Id) returns (bool) { HTLC storage htlc = contracts[Id]; if (htlc.refunded) revert AlreadyRefunded(); if (htlc.redeemed) revert AlreadyRedeemed(); if (htlc.timelock > block.timestamp) revert NotPassedTimelock(); htlc.refunded = true; (bool success, ) = htlc.sender.call{ value: htlc.amount }(''); require(success, 'Transfer failed'); emit TokenRefunded(Id); return true; } function addLock(bytes32 Id, bytes32 hashlock, uint256 timelock) external _exists(Id) returns (bytes32) { HTLC storage htlc = contracts[Id]; if (htlc.refunded == true) { revert AlreadyRefunded(); } if (timelock <= block.timestamp) { revert NotFutureTimelock(); } if (msg.sender == htlc.sender || msg.sender == htlc.messenger || msg.sender == address(this)) { if (htlc.hashlock == 0) { htlc.hashlock = hashlock; htlc.timelock = timelock; } else { revert HashlockAlreadySet(); } // DISCLAIMER: `tx.origin` is used in this event, but it can be misleading as it tracks the // original transaction sender, which could be different from the expected sender in complex // flows (e.g., a -> ... -> b -> c where the actual sender is b in event will be emitted a) emit TokenLockAdded(Id, tx.origin, hashlock, timelock); return Id; } else { revert NoAllowance(); } } function addLockSig(addLockMsg memory message, uint8 v, bytes32 r, bytes32 s) external returns (bytes32) { if (verifyMessage(message, v, r, s)) { return this.addLock(message.Id, message.hashlock, message.timelock); } else { revert InvalidSigniture(); } } function lock( bytes32 Id, bytes32 hashlock, uint256 timelock, address payable srcReceiver, string memory srcAsset, string memory dstChain, string memory dstAddress, string memory dstAsset, address messenger ) external payable returns (bytes32) { if (msg.value == 0) { revert FundsNotSent(); } if (timelock <= block.timestamp) { revert NotFutureTimelock(); } if (hasHTLC(Id)) { revert HTLCAlreadyExists(); } contracts[Id] = HTLC( dstAddress, dstChain, dstAsset, srcAsset, payable(msg.sender), srcReceiver, hashlock, timelock, msg.value, uint256(0), messenger, false, false ); contractIds.push(Id); emit TokenLocked( Id, hashlock, dstChain, dstAddress, dstAsset, msg.sender, srcReceiver, srcAsset, msg.value, timelock, messenger ); if (messenger != address(0)) { uint256 codeSize; assembly { codeSize := extcodesize(messenger) } if (codeSize > 0) { try IMessenger(messenger).notify( Id, 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(); } } return Id; } function redeem(bytes32 Id, uint256 secret) external _exists(Id) returns (bool) { HTLC storage htlc = contracts[Id]; if (htlc.hashlock != sha256(abi.encodePacked(secret))) revert HashlockNotMatch(); if (htlc.refunded) revert AlreadyRefunded(); 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(Id, msg.sender); return true; } function getDetails(bytes32 Id) public view returns (HTLC memory) { return contracts[Id]; } function getContracts(address senderAddr) public view returns (bytes32[] memory) { uint256 count = 0; for (uint256 i = 0; i < contractIds.length; i++) { HTLC memory htlc = contracts[contractIds[i]]; if (htlc.sender == senderAddr) { count++; } } bytes32[] memory result = new bytes32[](count); uint256 j = 0; for (uint256 i = 0; i < contractIds.length; i++) { if (contracts[contractIds[i]].sender == senderAddr) { result[j] = contractIds[i]; j++; } } return result; } function hashDomain(EIP712Domain memory domain) private pure returns (bytes32) { return keccak256( abi.encode( keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)'), keccak256(bytes(domain.name)), keccak256(bytes(domain.version)), domain.chainId, domain.verifyingContract, domain.salt ) ); } // Hashes an EIP712 message struct function hashMessage(addLockMsg memory message) private pure returns (bytes32) { return keccak256( abi.encode( keccak256('addLockMsg(bytes32 Id,bytes32 hashlock,uint256 timelock)'), message.Id, message.hashlock, message.timelock ) ); } // Verifies an EIP712 message signature function verifyMessage(addLockMsg memory message, uint8 v, bytes32 r, bytes32 s) private view returns (bool) { bytes32 digest = keccak256(abi.encodePacked('\x19\x01', DOMAIN_SEPARATOR, hashMessage(message))); address recoveredAddress = ecrecover(digest, v, r, s); return (recoveredAddress == contracts[message.Id].sender); } function hasHTLC(bytes32 Id) internal view returns (bool exists) { exists = (contracts[Id].sender != address(0)); } }
@openzeppelin/contracts/utils/Address.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } }
@openzeppelin/contracts/utils/cryptography/ECDSA.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.20; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS } /** * @dev The signature derives the `address(0)`. */ error ECDSAInvalidSignature(); /** * @dev The signature has an invalid length. */ error ECDSAInvalidSignatureLength(uint256 length); /** * @dev The signature has an S value that is in the upper half order. */ error ECDSAInvalidSignatureS(bytes32 s); /** * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not * return address(0) without also returning an error description. Errors are documented using an enum (error type) * and a bytes32 providing additional information about the error. * * If no error is returned, then the address can be used for verification purposes. * * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length)); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature); _throwError(error, errorArg); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) { unchecked { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); // We do not check for an overflow here since the shift operation results in 0 or 1. uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs); _throwError(error, errorArg); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError, bytes32) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n Ć· 2 + 1, and for v in (302): v ā {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS, s); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature, bytes32(0)); } return (signer, RecoverError.NoError, bytes32(0)); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s); _throwError(error, errorArg); return recovered; } /** * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided. */ function _throwError(RecoverError error, bytes32 errorArg) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert ECDSAInvalidSignature(); } else if (error == RecoverError.InvalidSignatureLength) { revert ECDSAInvalidSignatureLength(uint256(errorArg)); } else if (error == RecoverError.InvalidSignatureS) { revert ECDSAInvalidSignatureS(errorArg); } } }
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":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"error","name":"AlreadyLocked","inputs":[]},{"type":"error","name":"AlreadyRedeemed","inputs":[]},{"type":"error","name":"AlreadyRefunded","inputs":[]},{"type":"error","name":"FundsNotSent","inputs":[]},{"type":"error","name":"HTLCAlreadyExists","inputs":[]},{"type":"error","name":"HTLCNotExists","inputs":[]},{"type":"error","name":"HashlockAlreadySet","inputs":[]},{"type":"error","name":"HashlockNotMatch","inputs":[]},{"type":"error","name":"InvalidSigniture","inputs":[]},{"type":"error","name":"LockAlreadyExists","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":"Id","internalType":"bytes32","indexed":true},{"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":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}],"anonymous":false},{"type":"event","name":"TokenLockAdded","inputs":[{"type":"bytes32","name":"Id","internalType":"bytes32","indexed":true},{"type":"address","name":"messenger","internalType":"address","indexed":false},{"type":"bytes32","name":"hashlock","internalType":"bytes32","indexed":false},{"type":"uint256","name":"timelock","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TokenLocked","inputs":[{"type":"bytes32","name":"Id","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"hashlock","internalType":"bytes32","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":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}],"anonymous":false},{"type":"event","name":"TokenRedeemed","inputs":[{"type":"bytes32","name":"Id","internalType":"bytes32","indexed":true},{"type":"address","name":"redeemAddress","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"TokenRefunded","inputs":[{"type":"bytes32","name":"Id","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"addLock","inputs":[{"type":"bytes32","name":"Id","internalType":"bytes32"},{"type":"bytes32","name":"hashlock","internalType":"bytes32"},{"type":"uint256","name":"timelock","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"addLockSig","inputs":[{"type":"tuple","name":"message","internalType":"struct LayerswapV8.addLockMsg","components":[{"type":"bytes32","name":"Id","internalType":"bytes32"},{"type":"bytes32","name":"hashlock","internalType":"bytes32"},{"type":"uint256","name":"timelock","internalType":"uint256"}]},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"bytes32","name":"Id","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":"bytes32[]","name":"","internalType":"bytes32[]"}],"name":"getContracts","inputs":[{"type":"address","name":"senderAddr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct LayerswapV8.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":"timelock","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"secret","internalType":"uint256"},{"type":"address","name":"messenger","internalType":"address"},{"type":"bool","name":"redeemed","internalType":"bool"},{"type":"bool","name":"refunded","internalType":"bool"}]}],"name":"getDetails","inputs":[{"type":"bytes32","name":"Id","internalType":"bytes32"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"lock","inputs":[{"type":"bytes32","name":"Id","internalType":"bytes32"},{"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":"address","name":"messenger","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"redeem","inputs":[{"type":"bytes32","name":"Id","internalType":"bytes32"},{"type":"uint256","name":"secret","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"refund","inputs":[{"type":"bytes32","name":"Id","internalType":"bytes32"}]}]
Contract Creation Code
0x608060409080825234620001835760001943014381116200016d57406003556000908160045560208101906b098c2f2cae4e6eec2e040ac760a31b8252600c81526200004b8162000188565b51902082516001600160401b039390919060a083018581118482101762000159578082526200007a8162000188565b600b81526a098c2f2cae4e6eec2e0ac760ab1b60c08501528352805192620000a28462000188565b600184526020840190603160f81b825284602082015246838201523060608201528360808201525160208151910120935190209181519260208401947fd87cd6ef79d4e2b95e15ce8abf732db51ec771f1ca2edccf22a46c729ac5647286528385015260608401524660808401523060a084015260c083015260c0825260e082019482861090861117620001455784905251902090556122cf9081620001bb8239f35b634e487b7160e01b84526041600452602484fd5b634e487b7160e01b85526041600452602485fd5b634e487b7160e01b600052601160045260246000fd5b600080fd5b604081019081106001600160401b03821117620001a457604052565b634e487b7160e01b600052604160045260246000fdfe610120604052600436101561001357600080fd5b600061010052610100513560e01c8063213fe2b71461195b5780635ea66c3914610f79578063673da15414610e1c5780637249fbb614610cf857806375ad188114610c9e578063984bc70014610a48578063beeaa615146109be5763def944071461007d57600080fd5b6101403660031901126109b7576004356001600160401b0381116109b7576100a9903690600401611c9a565b60c052602480356001600160401b0381116109b7576100cc903690600401611c9a565b6044356001600160401b0381116109b7576100eb903690600401611c9a565b6064356001600160401b0381116109b75761010a903690600401611bf4565b906084356001600160401b0381116109b75761012a903690600401611bf4565b9160a4356001600160401b0381116109b75761014a903690600401611bf4565b9160c4356001600160401b0381116109b75761016a903690600401611bf4565b60e435969095906001600160a01b03881688036109b2576101243560a08190526001600160a01b03811690036109b25734156109a0574261010435111561098e5760045460018101811161097657806001809201600455016003541860e0526101ed60e051600052600160205260018060a01b0360046040600020015416151590565b610964576101fc60e051611e6a565b60405161020881611b9c565b85815284602082015286604082015287606082015233608082015260018060a01b03891660a08201526101005160c08201526101043560e0820152346101008201526101005161012082015260018060a01b0360a05116610140820152610100516101608201526101005161018082015260e05161010051526001602052604061010051209181518051906001600160401b0382116107a05781906102ad8654611d66565b601f8111610910575b506020906001601f84111461089e576101005192610893575b50508160011b916000199060031b1c19161783555b60208201518051906001600160401b0382116107a05781906103096001870154611d66565b601f811161083c575b506020906001601f8411146107c45761010051926107b9575b50508160011b916000199060031b1c19161760018401555b60408201518051906001600160401b0382116107a05781906103686002870154611d66565b601f8111610749575b506020906001601f8411146106d95761010051926106ce575b50508160011b916000199060031b1c19161760028401555b60608201519081516080526001600160401b03608051116106b757506103cb6003840154611d66565b601f8111610668575b5061010051506020601f608051116001146105c557610558989561051261053c966104f06101409d9b9761018061052e9861054a9d986105209861010051916080516105ba575b505060805160011b9060001960805160031b1c19161760038401555b60808101516004840180546001600160a01b03199081166001600160a01b039384161790915560a0838101516005870180549093169084161790915560c0830151600686015560e0830151600786015561010083015160088601556101208301516009860155610140830151600a9590950180546101608501516001600160a81b03199091169690931695909517911515901b60ff60a01b161783555b0151815460ff60a81b191690151560a81b60ff60a81b16179055565b6105046040519d8e8181520160c05161223c565b8d810360208f01529061223c565b908b820360408d015261223c565b9089820360608b0152611c5e565b908782036080890152611c5e565b9085820360a0870152611c5e565b9083820360c0850152611c5e565b913460e08301526101043561010083015260018060a01b0360a0511661012083015260018060a01b0316917f625ba51e51c5f2c394db4494f428998d9a34cd2f81e1ff9f134570a67f92ac4633928060e051930390a4602060405160e0518152f35b01519050388061041b565b6003840161010051526020610100512091610100515b608051601f1916811061065057509561051261053c966104f06101409d9b9761018061052e986105589f9c986105209861054a9f9a608051601f196080511610610635575b5050506001608051811b016003840155610437565b015160001960f860805160031b161c19169055388080610620565b919260206001819286850151815501940192016105db565b60038401610100515260206101005120601f6080510160051c81016020608051106106b0575b601f830160051c820181106106a45750506103d4565b6000815560010161068e565b508061068e565b6101008051634e487b7160e01b9052604160045251fd5b01519050388061038a565b610100805160028901905251602081209350601f198516905b8181106107315750908460019594939210610718575b505050811b0160028401556103a2565b015160001960f88460031b161c19169055388080610708565b929360206001819287860151815501950193016106f2565b90915060028601610100515260206101005120601f840160051c810160208510610799575b90849392915b601f830160051c8201811061078a575050610371565b60008155859450600101610774565b508061076e565b82634e487b7160e01b6101005152604160045261010051fd5b01519050388061032b565b9250600186016101005152602061010051209061010051935b601f1984168510610821576001945083601f19811610610808575b505050811b016001840155610343565b015160001960f88460031b161c191690553880806107f8565b818101518355602094850194600190930192909101906107dd565b90915060018601610100515260206101005120601f840160051c81016020851061088c575b90849392915b601f830160051c8201811061087d575050610312565b60008155859450600101610867565b5080610861565b0151905038806102cf565b9250856101005152602061010051209061010051935b601f19841685106108f5576001945083601f198116106108dc575b505050811b0183556102e4565b015160001960f88460031b161c191690553880806108cf565b818101518355602094850194600190930192909101906108b4565b90915085610100515260206101005120601f840160051c81016020851061095d575b90849392915b601f830160051c8201811061094e5750506102b6565b60008155859450600101610938565b5080610932565b604051630ed8e66b60e21b8152600490fd5b506101008051634e487b7160e01b9052601160045251fd5b604051633dd8280960e21b8152600490fd5b604051636f8ab38d60e11b8152600490fd5b600080fd5b6101005180fd5b346109b757366003190160c081126109b7576060136109b757604051606081018181106001600160401b03821117610a32576040526004358152602435602082015260443560408201526064359060ff821682036109b757602091610a2a9160a4359160843591612080565b604051908152f35b634e487b7160e01b600052604160045260246000fd5b346109b75760203660031901126109b757604051610a6581611b9c565b6060815260606020820152606060408201526060808201526101005160808201526101005160a08201526101005160c08201526101005160e08201526101005161010082015261010051610120820152610100516101408201526101005161016082015261018061010051910152600435610100515260016020526040610100512060ff600a60405192610af884611b9c565b610b0181611da0565b8452610b0f60018201611da0565b6020850152610b2060028201611da0565b6040850152610b3160038201611da0565b606085015260018060a01b03600482015416608085015260018060a01b0360058201541660a0850152600681015460c0850152600781015460e085015260088101546101008501526009810154610120850152015460018060a01b038116610140840152818160a01c16151561016084015260a81c161515610180820152604051809160208252610180610c1e610bd683516101a060208701526101c0860190611c5e565b610c09610bf5602086015192601f1993848983030160408a0152611c5e565b604086015183888303016060890152611c5e565b90606085015190868303016080870152611c5e565b9160018060a01b0360808201511660a085015260018060a01b0360a08201511660c085015260c081015160e085015260e081015161010085015261010081015161012085015261012081015161014085015260018060a01b0361014082015116610160850152610160810151151582850152015115156101a08301520390f35b346109b75760603660031901126109b757600480356000818152600160205260409020909101546001600160a01b031615610ce657610a2a6020916044359060243590611f85565b6040516368cadcd560e01b8152600490fd5b346109b75760203660031901126109b757600480356000818152600160205260409020909101546001600160a01b031615610ce65780610100515260016020526040610100512090600a82019182549060ff8260a81c16610e0a5760ff8260a01c16610df85760078101544210610de65760ff60a81b19909116600160a81b17909255600482015461010051600890930154602093610db29290918291829182916001600160a01b03165af1610dac611f17565b50611f47565b604051907f92b8d387b3b4732fb701784c5e553091c36997ec127e0865a7c990bc62cc73826101005161010051a260018152f35b60405163b3f711f760e01b8152600490fd5b6040516306d3830f60e21b8152600490fd5b60405163542f378d60e11b8152600490fd5b346109b75760403660031901126109b7576004803560008181526001602052604090209091015460243591906001600160a01b031615610ce6578061010051526020916001835260406101005120600681015460405185810184815286825260408201908282106001600160401b03831117610a32578792610ea78392836040528251948591611c3b565b61010051928101039060025afa15610f6b57610100515103610f5957600a8101805460ff8160a81c16610e0a5760ff8160a01c16610df857600983019390935560ff60a01b19909216600160a01b17909155600581015461010051600890920154610f279291829182918291906001600160a01b03165af1610dac611f17565b7f0f7c50d316885e5d3719752f760bbbbf7d56363501e721eea4d913e255b632e482604051338152a260405160018152f35b60405163e73bcb3560e01b8152600490fd5b6040513d61010051823e3d90fd5b6101203660031901126109b7576064356001600160a01b03811681036109b7576084356001600160401b0381116109b757610fb8903690600401611bf4565b9060a4356001600160401b0381116109b757610fd8903690600401611bf4565b9160c4356001600160401b0381116109b757610ff8903690600401611bf4565b9060e4356001600160401b0381116109b757611018903690600401611bf4565b610104356001600160a01b03811690036109b75734156109a05742604435111561098e5760048035600090815260016020526040902001546001600160a01b03166109645760405161106981611b9c565b83815285602082015281604082015282606082015233608082015260018060a01b03851660a082015260243560c082015260443560e0820152346101008201526101005161012082015260018060a01b036101043516610140820152610100516101608201526101005161018082015260043561010051526001602052604061010051209080518051906001600160401b0382116115ce57819061110d8554611d66565b601f8111611905575b506020906001601f841114611893576101005192611888575b50508160011b916000199060031b1c19161782555b60208101518051906001600160401b0382116115ce5781906111696001860154611d66565b601f811161182f575b506020906001601f8411146117b75761010051926117ac575b50508160011b916000199060031b1c19161760018301555b60408101518051906001600160401b0382116115ce5781906111c86002860154611d66565b601f8111611753575b506020906001601f8411146116db5761010051926116d0575b50508160011b916000199060031b1c19161760028301555b60608101518051906001600160401b0382116115ce576112256003850154611d66565b601f8111611683575b506020906001601f84111461160557918061130b9594926101809461010051926115fa575b50508160011b916000199060031b1c191617600384015560808101516004840180546001600160a01b03199081166001600160a01b039384161790915560a0838101516005870180549093169084161790915560c0830151600686015560e0830151600786015561010083015160088601556101208301516009860155610140830151600a9590950180546101608501516001600160a81b03199091169690931695909517911515901b60ff60a01b161783556104d4565b611316600435611e6a565b6040516024358152610100602082015261136761135961134b61133d61010085018a611c5e565b848103604086015287611c5e565b838103606085015284611c5e565b828103608084015284611c5e565b3460a083015260443560c08301526001600160a01b0361010435811660e08401528616913391600435917f3b0d81a1222f6461aad9f7e61041b1d52638afa81257eced76b240abc105de519181900390a4610104356001600160a01b03166113d6575b60206040516004358152f35b610104353b156115e857610104356001600160a01b03163b156109b757611468926114446114569261143260405198635e863a5b60e01b8a5260043560048b015260243560248b015261016060448b01526101648a0190611c5e565b8881036003190160648a015290611c5e565b86810360031901608488015290611c5e565b8481036003190160a486015290611c5e565b3360c48401526001600160a01b0391821660e48401523461010480850191909152604435610124850152610100805161014486015251928492839003918391859135165af190816115b7575b506115ad576101005160033d11611594575b6308c379a014611559575b7f7b5bdb2f87e8e20f082bba9be5f7e870728f9bba18540559ccdcdcbb1fc5a0876115116114fd611f17565b604051918291602083526020830190611c5e565b0390a160405162461bcd60e51b815260206004820152601860248201527f494d657373656e676572206e6f74696679206661696c656400000000000000006044820152606490fd5b611561611ea6565b8061156c57506114d1565b60405162461bcd60e51b815260206004820152908190611590906024830190611c5e565b0390fd5b50600461010051610100513e610100515160e01c6114c6565b80808080806113ca565b6001600160401b0381116115ce57604052816114b4565b634e487b7160e01b61010051526041600452602461010051fd5b604051633127e9d760e11b8152600490fd5b015190508b80611253565b906003850161010051526020610100512091610100515b601f198516811061166b57509261130b9594926001926101809583601f19811610611652575b505050811b016003840155610437565b015160001960f88460031b161c191690558b8080611642565b9192602060018192868501518155019401920161161c565b60038501610100515260206101005120601f840160051c8101602085106116c9575b601f830160051c820181106116bb57505061122e565b6101005181556001016116a5565b50806116a5565b0151905089806111ea565b9250600285016101005152602061010051209061010051935b601f1984168510611738576001945083601f1981161061171f575b505050811b016002830155611202565b015160001960f88460031b161c1916905589808061170f565b818101518355602094850194600190930192909101906116f4565b90915060028501610100515260206101005120601f840160051c8101602085106117a5575b90849392915b601f830160051c820181106117945750506111d1565b61010051815585945060010161177e565b5080611778565b01519050898061118b565b9250600185016101005152602061010051209061010051935b601f1984168510611814576001945083601f198116106117fb575b505050811b0160018301556111a3565b015160001960f88460031b161c191690558980806117eb565b818101518355602094850194600190930192909101906117d0565b90915060018501610100515260206101005120601f840160051c810160208510611881575b90849392915b601f830160051c82018110611870575050611172565b61010051815585945060010161185a565b5080611854565b01519050898061112f565b9250846101005152602061010051209061010051935b601f19841685106118ea576001945083601f198116106118d1575b505050811b018255611144565b015160001960f88460031b161c191690558980806118c4565b818101518355602094850194600190930192909101906118a9565b90915084610100515260206101005120601f840160051c810160208510611954575b90849392915b601f830160051c82018110611943575050611116565b61010051815585945060010161192d565b5080611927565b346109b7576020806003193601126109b7576001600160a01b03600435818116908190036109b7576101005160028054919290835b838110611aa05750506119bb6119a584611c83565b936119b36040519586611bb8565b808552611c83565b8386019490601f19013686376101005191825b848110611a1a578786886040519283928184019082855251809152604084019291610100515b828110611a0357505050500390f35b8351855286955093810193928101926001016119f4565b611a2381611d19565b9054600391821b1c610100515260018952828460046040610100512001541614611a51575b506001016119ce565b611a5c829592611d19565b9054911b1c8651821015611a865781611a7f918a60019460051b8a010152611e45565b9390611a48565b634e487b7160e01b61010051526032600452602461010051fd5b82611aaa82611d19565b9054600391821b1c61010051526001808a52611b046040610100512092611ae960405193611ad785611b9c565b611ae086611da0565b85528501611da0565b8c840152611af8878501611da0565b60408401528301611da0565b60608201526101808960048401541692836080840152600a8b6005830154169160a09283860152600681015460c0860152600781015460e086015260088101546101008601526009810154610120860152015480918c821661014086015260ff9283911c16151561016085015260a81c16151591015214611b88575b600101611990565b93611b94600191611e45565b949050611b80565b6101a081019081106001600160401b03821117610a3257604052565b90601f801991011681019081106001600160401b03821117610a3257604052565b6001600160401b038111610a3257601f01601f191660200190565b81601f820112156109b257803590611c0b82611bd9565b92611c196040519485611bb8565b828452602083830101116109b257816000926020809301838601378301015290565b60005b838110611c4e5750506000910152565b8181015183820152602001611c3e565b90602091611c7781518092818552858086019101611c3b565b601f01601f1916010190565b6001600160401b038111610a325760051b60200190565b81601f820112156109b257803591602091611cb484611c83565b93611cc26040519586611bb8565b808552838086019160051b830101928084116109b257848301915b848310611ced5750505050505090565b82356001600160401b0381116109b2578691611d0e84848094890101611bf4565b815201920191611cdd565b600254811015611d505760026000527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0190600090565b634e487b7160e01b600052603260045260246000fd5b90600182811c92168015611d96575b6020831014611d8057565b634e487b7160e01b600052602260045260246000fd5b91607f1691611d75565b90604051918260008254611db381611d66565b90818452602094600191600181169081600014611e235750600114611de4575b505050611de292500383611bb8565b565b600090815285812095935091905b818310611e0b575050611de29350820101388080611dd3565b85548884018501529485019487945091830191611df2565b92505050611de294925060ff191682840152151560051b820101388080611dd3565b6000198114611e545760010190565b634e487b7160e01b600052601160045260246000fd5b60025468010000000000000000811015610a3257806001611e8e9201600255611d19565b819291549060031b91821b91600019901b1916179055565b600060443d10611f0357604051600319913d83016004833e81516001600160401b03918282113d602484011117611f0657818401948551938411611f0e573d85010160208487010111611f065750611f0392910160200190611bb8565b90565b949350505050565b50949350505050565b3d15611f42573d90611f2882611bd9565b91611f366040519384611bb8565b82523d6000602084013e565b606090565b15611f4e57565b60405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606490fd5b91826000526001602052604080600020600a810154600160ff8260a81c1615151461206f574284111561205e576004820154336001600160a01b0391821614918215612051575b50508015612048575b15612037576006810180546120265792606092816007879489987fc444cd90bb87c0733c799513fba068d7635632ccbd9dffb878caa3d2b2783971985501558051923284526020840152820152a290565b8251636e6870d560e01b8152600490fd5b8151631d7eb35960e31b8152600490fd5b50303314611fd5565b9091501633143880611fcc565b8251633dd8280960e21b8152600490fd5b825163542f378d60e11b8152600490fd5b919092600091825493805194602093848301968751946040998a94858701978851908751958b8701987f45906d7e53feffed68a8db947e0f8839b1ee252166e8eead8c6ab3951a09c7b68a52870152606086015260808501526080845260a084016001600160401b03968582108883111761222857818e528551902060c086019261190160f01b845260c287015260e2860152604281526101208501968188109088111761221457868d52519020855260ff1661014083015261016082015261018001528480528390859060809060015afa1561220a5783518151855260018452868520600401546001600160a01b039182169116036121f9575193519051908551946375ad188160e01b8652600486015260248501526044840152808360648185305af19384156121ee575081936121ba575b50505090565b9091809350813d83116121e7575b6121d28183611bb8565b810103126121e45750513880806121b4565b80fd5b503d6121c8565b51913d9150823e3d90fd5b855163553470cf60e01b8152600490fd5b85513d85823e3d90fd5b634e487b7160e01b8b52604160045260248bfd5b634e487b7160e01b8c52604160045260248cfd5b90808251908181526020809101926020808460051b8301019501936000915b84831061226b5750505050505090565b9091929394958480612289600193601f198682030187528a51611c5e565b980193019301919493929061225b56fea26469706673582212208d5aabdb882842e5111b2e2dfb68b3d6da222709f9de41000a928a8e374e047b64736f6c63430008170033
Deployed ByteCode
0x610120604052600436101561001357600080fd5b600061010052610100513560e01c8063213fe2b71461195b5780635ea66c3914610f79578063673da15414610e1c5780637249fbb614610cf857806375ad188114610c9e578063984bc70014610a48578063beeaa615146109be5763def944071461007d57600080fd5b6101403660031901126109b7576004356001600160401b0381116109b7576100a9903690600401611c9a565b60c052602480356001600160401b0381116109b7576100cc903690600401611c9a565b6044356001600160401b0381116109b7576100eb903690600401611c9a565b6064356001600160401b0381116109b75761010a903690600401611bf4565b906084356001600160401b0381116109b75761012a903690600401611bf4565b9160a4356001600160401b0381116109b75761014a903690600401611bf4565b9160c4356001600160401b0381116109b75761016a903690600401611bf4565b60e435969095906001600160a01b03881688036109b2576101243560a08190526001600160a01b03811690036109b25734156109a0574261010435111561098e5760045460018101811161097657806001809201600455016003541860e0526101ed60e051600052600160205260018060a01b0360046040600020015416151590565b610964576101fc60e051611e6a565b60405161020881611b9c565b85815284602082015286604082015287606082015233608082015260018060a01b03891660a08201526101005160c08201526101043560e0820152346101008201526101005161012082015260018060a01b0360a05116610140820152610100516101608201526101005161018082015260e05161010051526001602052604061010051209181518051906001600160401b0382116107a05781906102ad8654611d66565b601f8111610910575b506020906001601f84111461089e576101005192610893575b50508160011b916000199060031b1c19161783555b60208201518051906001600160401b0382116107a05781906103096001870154611d66565b601f811161083c575b506020906001601f8411146107c45761010051926107b9575b50508160011b916000199060031b1c19161760018401555b60408201518051906001600160401b0382116107a05781906103686002870154611d66565b601f8111610749575b506020906001601f8411146106d95761010051926106ce575b50508160011b916000199060031b1c19161760028401555b60608201519081516080526001600160401b03608051116106b757506103cb6003840154611d66565b601f8111610668575b5061010051506020601f608051116001146105c557610558989561051261053c966104f06101409d9b9761018061052e9861054a9d986105209861010051916080516105ba575b505060805160011b9060001960805160031b1c19161760038401555b60808101516004840180546001600160a01b03199081166001600160a01b039384161790915560a0838101516005870180549093169084161790915560c0830151600686015560e0830151600786015561010083015160088601556101208301516009860155610140830151600a9590950180546101608501516001600160a81b03199091169690931695909517911515901b60ff60a01b161783555b0151815460ff60a81b191690151560a81b60ff60a81b16179055565b6105046040519d8e8181520160c05161223c565b8d810360208f01529061223c565b908b820360408d015261223c565b9089820360608b0152611c5e565b908782036080890152611c5e565b9085820360a0870152611c5e565b9083820360c0850152611c5e565b913460e08301526101043561010083015260018060a01b0360a0511661012083015260018060a01b0316917f625ba51e51c5f2c394db4494f428998d9a34cd2f81e1ff9f134570a67f92ac4633928060e051930390a4602060405160e0518152f35b01519050388061041b565b6003840161010051526020610100512091610100515b608051601f1916811061065057509561051261053c966104f06101409d9b9761018061052e986105589f9c986105209861054a9f9a608051601f196080511610610635575b5050506001608051811b016003840155610437565b015160001960f860805160031b161c19169055388080610620565b919260206001819286850151815501940192016105db565b60038401610100515260206101005120601f6080510160051c81016020608051106106b0575b601f830160051c820181106106a45750506103d4565b6000815560010161068e565b508061068e565b6101008051634e487b7160e01b9052604160045251fd5b01519050388061038a565b610100805160028901905251602081209350601f198516905b8181106107315750908460019594939210610718575b505050811b0160028401556103a2565b015160001960f88460031b161c19169055388080610708565b929360206001819287860151815501950193016106f2565b90915060028601610100515260206101005120601f840160051c810160208510610799575b90849392915b601f830160051c8201811061078a575050610371565b60008155859450600101610774565b508061076e565b82634e487b7160e01b6101005152604160045261010051fd5b01519050388061032b565b9250600186016101005152602061010051209061010051935b601f1984168510610821576001945083601f19811610610808575b505050811b016001840155610343565b015160001960f88460031b161c191690553880806107f8565b818101518355602094850194600190930192909101906107dd565b90915060018601610100515260206101005120601f840160051c81016020851061088c575b90849392915b601f830160051c8201811061087d575050610312565b60008155859450600101610867565b5080610861565b0151905038806102cf565b9250856101005152602061010051209061010051935b601f19841685106108f5576001945083601f198116106108dc575b505050811b0183556102e4565b015160001960f88460031b161c191690553880806108cf565b818101518355602094850194600190930192909101906108b4565b90915085610100515260206101005120601f840160051c81016020851061095d575b90849392915b601f830160051c8201811061094e5750506102b6565b60008155859450600101610938565b5080610932565b604051630ed8e66b60e21b8152600490fd5b506101008051634e487b7160e01b9052601160045251fd5b604051633dd8280960e21b8152600490fd5b604051636f8ab38d60e11b8152600490fd5b600080fd5b6101005180fd5b346109b757366003190160c081126109b7576060136109b757604051606081018181106001600160401b03821117610a32576040526004358152602435602082015260443560408201526064359060ff821682036109b757602091610a2a9160a4359160843591612080565b604051908152f35b634e487b7160e01b600052604160045260246000fd5b346109b75760203660031901126109b757604051610a6581611b9c565b6060815260606020820152606060408201526060808201526101005160808201526101005160a08201526101005160c08201526101005160e08201526101005161010082015261010051610120820152610100516101408201526101005161016082015261018061010051910152600435610100515260016020526040610100512060ff600a60405192610af884611b9c565b610b0181611da0565b8452610b0f60018201611da0565b6020850152610b2060028201611da0565b6040850152610b3160038201611da0565b606085015260018060a01b03600482015416608085015260018060a01b0360058201541660a0850152600681015460c0850152600781015460e085015260088101546101008501526009810154610120850152015460018060a01b038116610140840152818160a01c16151561016084015260a81c161515610180820152604051809160208252610180610c1e610bd683516101a060208701526101c0860190611c5e565b610c09610bf5602086015192601f1993848983030160408a0152611c5e565b604086015183888303016060890152611c5e565b90606085015190868303016080870152611c5e565b9160018060a01b0360808201511660a085015260018060a01b0360a08201511660c085015260c081015160e085015260e081015161010085015261010081015161012085015261012081015161014085015260018060a01b0361014082015116610160850152610160810151151582850152015115156101a08301520390f35b346109b75760603660031901126109b757600480356000818152600160205260409020909101546001600160a01b031615610ce657610a2a6020916044359060243590611f85565b6040516368cadcd560e01b8152600490fd5b346109b75760203660031901126109b757600480356000818152600160205260409020909101546001600160a01b031615610ce65780610100515260016020526040610100512090600a82019182549060ff8260a81c16610e0a5760ff8260a01c16610df85760078101544210610de65760ff60a81b19909116600160a81b17909255600482015461010051600890930154602093610db29290918291829182916001600160a01b03165af1610dac611f17565b50611f47565b604051907f92b8d387b3b4732fb701784c5e553091c36997ec127e0865a7c990bc62cc73826101005161010051a260018152f35b60405163b3f711f760e01b8152600490fd5b6040516306d3830f60e21b8152600490fd5b60405163542f378d60e11b8152600490fd5b346109b75760403660031901126109b7576004803560008181526001602052604090209091015460243591906001600160a01b031615610ce6578061010051526020916001835260406101005120600681015460405185810184815286825260408201908282106001600160401b03831117610a32578792610ea78392836040528251948591611c3b565b61010051928101039060025afa15610f6b57610100515103610f5957600a8101805460ff8160a81c16610e0a5760ff8160a01c16610df857600983019390935560ff60a01b19909216600160a01b17909155600581015461010051600890920154610f279291829182918291906001600160a01b03165af1610dac611f17565b7f0f7c50d316885e5d3719752f760bbbbf7d56363501e721eea4d913e255b632e482604051338152a260405160018152f35b60405163e73bcb3560e01b8152600490fd5b6040513d61010051823e3d90fd5b6101203660031901126109b7576064356001600160a01b03811681036109b7576084356001600160401b0381116109b757610fb8903690600401611bf4565b9060a4356001600160401b0381116109b757610fd8903690600401611bf4565b9160c4356001600160401b0381116109b757610ff8903690600401611bf4565b9060e4356001600160401b0381116109b757611018903690600401611bf4565b610104356001600160a01b03811690036109b75734156109a05742604435111561098e5760048035600090815260016020526040902001546001600160a01b03166109645760405161106981611b9c565b83815285602082015281604082015282606082015233608082015260018060a01b03851660a082015260243560c082015260443560e0820152346101008201526101005161012082015260018060a01b036101043516610140820152610100516101608201526101005161018082015260043561010051526001602052604061010051209080518051906001600160401b0382116115ce57819061110d8554611d66565b601f8111611905575b506020906001601f841114611893576101005192611888575b50508160011b916000199060031b1c19161782555b60208101518051906001600160401b0382116115ce5781906111696001860154611d66565b601f811161182f575b506020906001601f8411146117b75761010051926117ac575b50508160011b916000199060031b1c19161760018301555b60408101518051906001600160401b0382116115ce5781906111c86002860154611d66565b601f8111611753575b506020906001601f8411146116db5761010051926116d0575b50508160011b916000199060031b1c19161760028301555b60608101518051906001600160401b0382116115ce576112256003850154611d66565b601f8111611683575b506020906001601f84111461160557918061130b9594926101809461010051926115fa575b50508160011b916000199060031b1c191617600384015560808101516004840180546001600160a01b03199081166001600160a01b039384161790915560a0838101516005870180549093169084161790915560c0830151600686015560e0830151600786015561010083015160088601556101208301516009860155610140830151600a9590950180546101608501516001600160a81b03199091169690931695909517911515901b60ff60a01b161783556104d4565b611316600435611e6a565b6040516024358152610100602082015261136761135961134b61133d61010085018a611c5e565b848103604086015287611c5e565b838103606085015284611c5e565b828103608084015284611c5e565b3460a083015260443560c08301526001600160a01b0361010435811660e08401528616913391600435917f3b0d81a1222f6461aad9f7e61041b1d52638afa81257eced76b240abc105de519181900390a4610104356001600160a01b03166113d6575b60206040516004358152f35b610104353b156115e857610104356001600160a01b03163b156109b757611468926114446114569261143260405198635e863a5b60e01b8a5260043560048b015260243560248b015261016060448b01526101648a0190611c5e565b8881036003190160648a015290611c5e565b86810360031901608488015290611c5e565b8481036003190160a486015290611c5e565b3360c48401526001600160a01b0391821660e48401523461010480850191909152604435610124850152610100805161014486015251928492839003918391859135165af190816115b7575b506115ad576101005160033d11611594575b6308c379a014611559575b7f7b5bdb2f87e8e20f082bba9be5f7e870728f9bba18540559ccdcdcbb1fc5a0876115116114fd611f17565b604051918291602083526020830190611c5e565b0390a160405162461bcd60e51b815260206004820152601860248201527f494d657373656e676572206e6f74696679206661696c656400000000000000006044820152606490fd5b611561611ea6565b8061156c57506114d1565b60405162461bcd60e51b815260206004820152908190611590906024830190611c5e565b0390fd5b50600461010051610100513e610100515160e01c6114c6565b80808080806113ca565b6001600160401b0381116115ce57604052816114b4565b634e487b7160e01b61010051526041600452602461010051fd5b604051633127e9d760e11b8152600490fd5b015190508b80611253565b906003850161010051526020610100512091610100515b601f198516811061166b57509261130b9594926001926101809583601f19811610611652575b505050811b016003840155610437565b015160001960f88460031b161c191690558b8080611642565b9192602060018192868501518155019401920161161c565b60038501610100515260206101005120601f840160051c8101602085106116c9575b601f830160051c820181106116bb57505061122e565b6101005181556001016116a5565b50806116a5565b0151905089806111ea565b9250600285016101005152602061010051209061010051935b601f1984168510611738576001945083601f1981161061171f575b505050811b016002830155611202565b015160001960f88460031b161c1916905589808061170f565b818101518355602094850194600190930192909101906116f4565b90915060028501610100515260206101005120601f840160051c8101602085106117a5575b90849392915b601f830160051c820181106117945750506111d1565b61010051815585945060010161177e565b5080611778565b01519050898061118b565b9250600185016101005152602061010051209061010051935b601f1984168510611814576001945083601f198116106117fb575b505050811b0160018301556111a3565b015160001960f88460031b161c191690558980806117eb565b818101518355602094850194600190930192909101906117d0565b90915060018501610100515260206101005120601f840160051c810160208510611881575b90849392915b601f830160051c82018110611870575050611172565b61010051815585945060010161185a565b5080611854565b01519050898061112f565b9250846101005152602061010051209061010051935b601f19841685106118ea576001945083601f198116106118d1575b505050811b018255611144565b015160001960f88460031b161c191690558980806118c4565b818101518355602094850194600190930192909101906118a9565b90915084610100515260206101005120601f840160051c810160208510611954575b90849392915b601f830160051c82018110611943575050611116565b61010051815585945060010161192d565b5080611927565b346109b7576020806003193601126109b7576001600160a01b03600435818116908190036109b7576101005160028054919290835b838110611aa05750506119bb6119a584611c83565b936119b36040519586611bb8565b808552611c83565b8386019490601f19013686376101005191825b848110611a1a578786886040519283928184019082855251809152604084019291610100515b828110611a0357505050500390f35b8351855286955093810193928101926001016119f4565b611a2381611d19565b9054600391821b1c610100515260018952828460046040610100512001541614611a51575b506001016119ce565b611a5c829592611d19565b9054911b1c8651821015611a865781611a7f918a60019460051b8a010152611e45565b9390611a48565b634e487b7160e01b61010051526032600452602461010051fd5b82611aaa82611d19565b9054600391821b1c61010051526001808a52611b046040610100512092611ae960405193611ad785611b9c565b611ae086611da0565b85528501611da0565b8c840152611af8878501611da0565b60408401528301611da0565b60608201526101808960048401541692836080840152600a8b6005830154169160a09283860152600681015460c0860152600781015460e086015260088101546101008601526009810154610120860152015480918c821661014086015260ff9283911c16151561016085015260a81c16151591015214611b88575b600101611990565b93611b94600191611e45565b949050611b80565b6101a081019081106001600160401b03821117610a3257604052565b90601f801991011681019081106001600160401b03821117610a3257604052565b6001600160401b038111610a3257601f01601f191660200190565b81601f820112156109b257803590611c0b82611bd9565b92611c196040519485611bb8565b828452602083830101116109b257816000926020809301838601378301015290565b60005b838110611c4e5750506000910152565b8181015183820152602001611c3e565b90602091611c7781518092818552858086019101611c3b565b601f01601f1916010190565b6001600160401b038111610a325760051b60200190565b81601f820112156109b257803591602091611cb484611c83565b93611cc26040519586611bb8565b808552838086019160051b830101928084116109b257848301915b848310611ced5750505050505090565b82356001600160401b0381116109b2578691611d0e84848094890101611bf4565b815201920191611cdd565b600254811015611d505760026000527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0190600090565b634e487b7160e01b600052603260045260246000fd5b90600182811c92168015611d96575b6020831014611d8057565b634e487b7160e01b600052602260045260246000fd5b91607f1691611d75565b90604051918260008254611db381611d66565b90818452602094600191600181169081600014611e235750600114611de4575b505050611de292500383611bb8565b565b600090815285812095935091905b818310611e0b575050611de29350820101388080611dd3565b85548884018501529485019487945091830191611df2565b92505050611de294925060ff191682840152151560051b820101388080611dd3565b6000198114611e545760010190565b634e487b7160e01b600052601160045260246000fd5b60025468010000000000000000811015610a3257806001611e8e9201600255611d19565b819291549060031b91821b91600019901b1916179055565b600060443d10611f0357604051600319913d83016004833e81516001600160401b03918282113d602484011117611f0657818401948551938411611f0e573d85010160208487010111611f065750611f0392910160200190611bb8565b90565b949350505050565b50949350505050565b3d15611f42573d90611f2882611bd9565b91611f366040519384611bb8565b82523d6000602084013e565b606090565b15611f4e57565b60405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606490fd5b91826000526001602052604080600020600a810154600160ff8260a81c1615151461206f574284111561205e576004820154336001600160a01b0391821614918215612051575b50508015612048575b15612037576006810180546120265792606092816007879489987fc444cd90bb87c0733c799513fba068d7635632ccbd9dffb878caa3d2b2783971985501558051923284526020840152820152a290565b8251636e6870d560e01b8152600490fd5b8151631d7eb35960e31b8152600490fd5b50303314611fd5565b9091501633143880611fcc565b8251633dd8280960e21b8152600490fd5b825163542f378d60e11b8152600490fd5b919092600091825493805194602093848301968751946040998a94858701978851908751958b8701987f45906d7e53feffed68a8db947e0f8839b1ee252166e8eead8c6ab3951a09c7b68a52870152606086015260808501526080845260a084016001600160401b03968582108883111761222857818e528551902060c086019261190160f01b845260c287015260e2860152604281526101208501968188109088111761221457868d52519020855260ff1661014083015261016082015261018001528480528390859060809060015afa1561220a5783518151855260018452868520600401546001600160a01b039182169116036121f9575193519051908551946375ad188160e01b8652600486015260248501526044840152808360648185305af19384156121ee575081936121ba575b50505090565b9091809350813d83116121e7575b6121d28183611bb8565b810103126121e45750513880806121b4565b80fd5b503d6121c8565b51913d9150823e3d90fd5b855163553470cf60e01b8152600490fd5b85513d85823e3d90fd5b634e487b7160e01b8b52604160045260248bfd5b634e487b7160e01b8c52604160045260248cfd5b90808251908181526020809101926020808460051b8301019501936000915b84831061226b5750505050505090565b9091929394958480612289600193601f198682030187528a51611c5e565b980193019301919493929061225b56fea26469706673582212208d5aabdb882842e5111b2e2dfb68b3d6da222709f9de41000a928a8e374e047b64736f6c63430008170033