My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Latest 1 Deposit
L2 Txn Hash | L1 Deposit Txn | Value | Token | |
---|---|---|---|---|
0x30d5b208d988d21c10c37bcca049cfcc173efbf1513681ff70c98a7b9eb657c5 | 259 days 20 hrs ago | 0x8f8795fa899681e1df03af061385d7095b96d1d3a47df0cde008dc27773a46cf | 0.1 | Ether (ETH) |
[ Download CSV Export ]
Contract Name:
UltraLightNodeV2
Compiler Version
v0.7.6+commit.7338295f
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; pragma abicoder v2; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "./interfaces/ILayerZeroValidationLibrary.sol"; import "./interfaces/ILayerZeroReceiver.sol"; import "./interfaces/ILayerZeroTreasury.sol"; import "./interfaces/ILayerZeroEndpoint.sol"; // v2 import "./interfaces/ILayerZeroMessagingLibraryV2.sol"; import "./interfaces/ILayerZeroOracleV2.sol"; import "./interfaces/ILayerZeroUltraLightNodeV2.sol"; import "./interfaces/ILayerZeroRelayerV2.sol"; import "./NonceContract.sol"; contract UltraLightNodeV2 is ILayerZeroMessagingLibraryV2, ILayerZeroUltraLightNodeV2, ReentrancyGuard, Ownable { using SafeERC20 for IERC20; using SafeMath for uint; // Application config uint public constant CONFIG_TYPE_INBOUND_PROOF_LIBRARY_VERSION = 1; uint public constant CONFIG_TYPE_INBOUND_BLOCK_CONFIRMATIONS = 2; uint public constant CONFIG_TYPE_RELAYER = 3; uint public constant CONFIG_TYPE_OUTBOUND_PROOF_TYPE = 4; uint public constant CONFIG_TYPE_OUTBOUND_BLOCK_CONFIRMATIONS = 5; uint public constant CONFIG_TYPE_ORACLE = 6; // Token and Contracts IERC20 public layerZeroToken; ILayerZeroTreasury public treasuryContract; mapping(address => uint) public nativeFees; uint public treasuryZROFees; // User Application mapping(address => mapping(uint16 => ApplicationConfiguration)) public appConfig; // app address => chainId => config mapping(uint16 => ApplicationConfiguration) public defaultAppConfig; // default UA settings if no version specified mapping(uint16 => mapping(uint16 => bytes)) public defaultAdapterParams; // Validation mapping(uint16 => mapping(uint16 => address)) public inboundProofLibrary; // chainId => library Id => inboundProofLibrary contract mapping(uint16 => uint16) public maxInboundProofLibrary; // chainId => inboundProofLibrary mapping(uint16 => mapping(uint16 => bool)) public supportedOutboundProof; // chainId => outboundProofType => enabled mapping(uint16 => uint) public chainAddressSizeMap; mapping(address => mapping(uint16 => mapping(bytes32 => mapping(bytes32 => uint)))) public hashLookup; //[oracle][srcChainId][blockhash][datahash] -> confirmation mapping(uint16 => bytes32) public ulnLookup; // remote ulns ILayerZeroEndpoint public immutable endpoint; uint16 public immutable localChainId; NonceContract public immutable nonceContract; constructor(address _endpoint, address _nonceContract, uint16 _localChainId) { require(_endpoint != address(0x0), "LayerZero: endpoint cannot be zero address"); require(_nonceContract != address(0x0), "LayerZero: nonceContract cannot be zero address"); ILayerZeroEndpoint lzEndpoint = ILayerZeroEndpoint(_endpoint); localChainId = _localChainId; endpoint = lzEndpoint; nonceContract = NonceContract(_nonceContract); } // only the endpoint can call SEND() and setConfig() modifier onlyEndpoint() { require(address(endpoint) == msg.sender, "LayerZero: only endpoint"); _; } //---------------------------------------------------------------------------------- // PROTOCOL function validateTransactionProof( uint16 _srcChainId, address _dstAddress, uint _gasLimit, bytes32 _lookupHash, bytes32 _blockData, bytes calldata _transactionProof ) external override { // retrieve UA's configuration using the _dstAddress from arguments. ApplicationConfiguration memory uaConfig = _getAppConfig(_srcChainId, _dstAddress); // assert that the caller == UA's relayer require(uaConfig.relayer == msg.sender, "LayerZero: invalid relayer"); LayerZeroPacket.Packet memory _packet; uint remoteAddressSize = chainAddressSizeMap[_srcChainId]; require(remoteAddressSize != 0, "LayerZero: incorrect remote address size"); { // assert that the data submitted by UA's oracle have no fewer confirmations than UA's configuration uint storedConfirmations = hashLookup[uaConfig.oracle][_srcChainId][_lookupHash][_blockData]; require( storedConfirmations > 0 && storedConfirmations >= uaConfig.inboundBlockConfirmations, "LayerZero: not enough block confirmations" ); // decode address inboundProofLib = inboundProofLibrary[_srcChainId][uaConfig.inboundProofLibraryVersion]; _packet = ILayerZeroValidationLibrary(inboundProofLib).validateProof( _blockData, _transactionProof, remoteAddressSize ); } // packet content assertion require( ulnLookup[_srcChainId] == _packet.ulnAddress && _packet.ulnAddress != bytes32(0), "LayerZero: invalid _packet.ulnAddress" ); require(_packet.srcChainId == _srcChainId, "LayerZero: invalid srcChain Id"); // failsafe because the remoteAddress size being passed into validateProof trims the address this should not hit require(_packet.srcAddress.length == remoteAddressSize, "LayerZero: invalid srcAddress size"); require(_packet.dstChainId == localChainId, "LayerZero: invalid dstChain Id"); require(_packet.dstAddress == _dstAddress, "LayerZero: invalid dstAddress"); // if the dst is not a contract, then emit and return early. This will break inbound nonces, but this particular // path is already broken and wont ever be able to deliver anyways if (!_isContract(_dstAddress)) { emit InvalidDst( _packet.srcChainId, _packet.srcAddress, _packet.dstAddress, _packet.nonce, keccak256(_packet.payload) ); return; } bytes memory pathData = abi.encodePacked(_packet.srcAddress, _packet.dstAddress); emit PacketReceived( _packet.srcChainId, _packet.srcAddress, _packet.dstAddress, _packet.nonce, keccak256(_packet.payload) ); endpoint.receivePayload(_srcChainId, pathData, _dstAddress, _packet.nonce, _gasLimit, _packet.payload); } function send( address _ua, uint64, uint16 _dstChainId, bytes calldata _path, bytes calldata _payload, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams ) external payable override onlyEndpoint { address ua = _ua; uint16 dstChainId = _dstChainId; require(ulnLookup[dstChainId] != bytes32(0), "LayerZero: dstChainId does not exist"); bytes memory dstAddress; uint64 nonce; // code block for solving 'Stack Too Deep' { uint chainAddressSize = chainAddressSizeMap[dstChainId]; // path = remoteAddress + localAddress require( chainAddressSize != 0 && _path.length == 20 + chainAddressSize, "LayerZero: incorrect remote address size" ); address srcInPath; bytes memory path = _path; // copy to memory assembly { srcInPath := mload(add(add(path, 20), chainAddressSize)) // chainAddressSize + 20 } require(ua == srcInPath, "LayerZero: wrong path data"); dstAddress = _path[0:chainAddressSize]; nonce = nonceContract.increment(dstChainId, ua, path); } bytes memory payload = _payload; ApplicationConfiguration memory uaConfig = _getAppConfig(dstChainId, ua); // compute all the fees uint relayerFee = _handleRelayer(dstChainId, uaConfig, ua, payload.length, _adapterParams); uint oracleFee = _handleOracle(dstChainId, uaConfig, ua); uint nativeProtocolFee = _handleProtocolFee(relayerFee, oracleFee, ua, _zroPaymentAddress); // total native fee, does not include ZRO protocol fee uint totalNativeFee = relayerFee.add(oracleFee).add(nativeProtocolFee); // assert the user has attached enough native token for this address require(totalNativeFee <= msg.value, "LayerZero: not enough native for fees"); // refund if they send too much uint amount = msg.value.sub(totalNativeFee); if (amount > 0) { (bool success, ) = _refundAddress.call{value: amount}(""); require(success, "LayerZero: failed to refund"); } // emit the data packet bytes memory encodedPayload = abi.encodePacked(nonce, localChainId, ua, dstChainId, dstAddress, payload); emit Packet(encodedPayload); } function _handleRelayer( uint16 _dstChainId, ApplicationConfiguration memory _uaConfig, address _ua, uint _payloadSize, bytes memory _adapterParams ) internal returns (uint relayerFee) { if (_adapterParams.length == 0) { _adapterParams = defaultAdapterParams[_dstChainId][_uaConfig.outboundProofType]; } address relayerAddress = _uaConfig.relayer; ILayerZeroRelayerV2 relayer = ILayerZeroRelayerV2(relayerAddress); relayerFee = relayer.assignJob(_dstChainId, _uaConfig.outboundProofType, _ua, _payloadSize, _adapterParams); _creditNativeFee(relayerAddress, relayerFee); // emit the param events emit RelayerParams(_adapterParams, _uaConfig.outboundProofType); } function _handleOracle( uint16 _dstChainId, ApplicationConfiguration memory _uaConfig, address _ua ) internal returns (uint oracleFee) { address oracleAddress = _uaConfig.oracle; oracleFee = ILayerZeroOracleV2(oracleAddress).assignJob( _dstChainId, _uaConfig.outboundProofType, _uaConfig.outboundBlockConfirmations, _ua ); _creditNativeFee(oracleAddress, oracleFee); } function _handleProtocolFee( uint _relayerFee, uint _oracleFee, address _ua, address _zroPaymentAddress ) internal returns (uint protocolNativeFee) { // if no ZRO token or not specifying a payment address, pay in native token bool payInNative = _zroPaymentAddress == address(0x0) || address(layerZeroToken) == address(0x0); uint protocolFee = treasuryContract.getFees(!payInNative, _relayerFee, _oracleFee); if (protocolFee > 0) { if (payInNative) { address treasuryAddress = address(treasuryContract); _creditNativeFee(treasuryAddress, protocolFee); protocolNativeFee = protocolFee; } else { // zro payment address must equal the ua or the tx.origin otherwise the transaction reverts require( _zroPaymentAddress == _ua || _zroPaymentAddress == tx.origin, "LayerZero: must be paid by sender or origin" ); // transfer the LayerZero token to this contract from the payee layerZeroToken.safeTransferFrom(_zroPaymentAddress, address(this), protocolFee); treasuryZROFees = treasuryZROFees.add(protocolFee); } } } function _creditNativeFee(address _receiver, uint _amount) internal { nativeFees[_receiver] = nativeFees[_receiver].add(_amount); } // Can be called by any address to update a block header // can only upload new block data or the same block data with more confirmations function updateHash( uint16 _srcChainId, bytes32 _lookupHash, uint _confirmations, bytes32 _blockData ) external override { uint storedConfirmations = hashLookup[msg.sender][_srcChainId][_lookupHash][_blockData]; // if it has a record, requires a larger confirmation. require( storedConfirmations < _confirmations, "LayerZero: oracle data can only update if it has more confirmations" ); // set the new information into storage hashLookup[msg.sender][_srcChainId][_lookupHash][_blockData] = _confirmations; emit HashReceived(_srcChainId, msg.sender, _lookupHash, _blockData, _confirmations); } //---------------------------------------------------------------------------------- // Other Library Interfaces // default to DEFAULT setting if ZERO value function getAppConfig( uint16 _remoteChainId, address _ua ) external view override returns (ApplicationConfiguration memory) { return _getAppConfig(_remoteChainId, _ua); } function _getAppConfig(uint16 _remoteChainId, address _ua) internal view returns (ApplicationConfiguration memory) { ApplicationConfiguration memory config = appConfig[_ua][_remoteChainId]; ApplicationConfiguration storage defaultConfig = defaultAppConfig[_remoteChainId]; if (config.inboundProofLibraryVersion == 0) { config.inboundProofLibraryVersion = defaultConfig.inboundProofLibraryVersion; } if (config.inboundBlockConfirmations == 0) { config.inboundBlockConfirmations = defaultConfig.inboundBlockConfirmations; } if (config.relayer == address(0x0)) { config.relayer = defaultConfig.relayer; } if (config.outboundProofType == 0) { config.outboundProofType = defaultConfig.outboundProofType; } if (config.outboundBlockConfirmations == 0) { config.outboundBlockConfirmations = defaultConfig.outboundBlockConfirmations; } if (config.oracle == address(0x0)) { config.oracle = defaultConfig.oracle; } return config; } function setConfig( uint16 _remoteChainId, address _ua, uint _configType, bytes calldata _config ) external override onlyEndpoint { ApplicationConfiguration storage uaConfig = appConfig[_ua][_remoteChainId]; if (_configType == CONFIG_TYPE_INBOUND_PROOF_LIBRARY_VERSION) { uint16 inboundProofLibraryVersion = abi.decode(_config, (uint16)); require( inboundProofLibraryVersion <= maxInboundProofLibrary[_remoteChainId], "LayerZero: invalid inbound proof library version" ); uaConfig.inboundProofLibraryVersion = inboundProofLibraryVersion; } else if (_configType == CONFIG_TYPE_INBOUND_BLOCK_CONFIRMATIONS) { uint64 blockConfirmations = abi.decode(_config, (uint64)); uaConfig.inboundBlockConfirmations = blockConfirmations; } else if (_configType == CONFIG_TYPE_RELAYER) { address relayer = abi.decode(_config, (address)); uaConfig.relayer = relayer; } else if (_configType == CONFIG_TYPE_OUTBOUND_PROOF_TYPE) { uint16 outboundProofType = abi.decode(_config, (uint16)); require( supportedOutboundProof[_remoteChainId][outboundProofType] || outboundProofType == 0, "LayerZero: invalid outbound proof type" ); uaConfig.outboundProofType = outboundProofType; } else if (_configType == CONFIG_TYPE_OUTBOUND_BLOCK_CONFIRMATIONS) { uint64 blockConfirmations = abi.decode(_config, (uint64)); uaConfig.outboundBlockConfirmations = blockConfirmations; } else if (_configType == CONFIG_TYPE_ORACLE) { address oracle = abi.decode(_config, (address)); uaConfig.oracle = oracle; } else { revert("LayerZero: Invalid config type"); } emit AppConfigUpdated(_ua, _configType, _config); } function getConfig( uint16 _remoteChainId, address _ua, uint _configType ) external view override returns (bytes memory) { ApplicationConfiguration storage uaConfig = appConfig[_ua][_remoteChainId]; if (_configType == CONFIG_TYPE_INBOUND_PROOF_LIBRARY_VERSION) { if (uaConfig.inboundProofLibraryVersion == 0) { return abi.encode(defaultAppConfig[_remoteChainId].inboundProofLibraryVersion); } return abi.encode(uaConfig.inboundProofLibraryVersion); } else if (_configType == CONFIG_TYPE_INBOUND_BLOCK_CONFIRMATIONS) { if (uaConfig.inboundBlockConfirmations == 0) { return abi.encode(defaultAppConfig[_remoteChainId].inboundBlockConfirmations); } return abi.encode(uaConfig.inboundBlockConfirmations); } else if (_configType == CONFIG_TYPE_RELAYER) { if (uaConfig.relayer == address(0x0)) { return abi.encode(defaultAppConfig[_remoteChainId].relayer); } return abi.encode(uaConfig.relayer); } else if (_configType == CONFIG_TYPE_OUTBOUND_PROOF_TYPE) { if (uaConfig.outboundProofType == 0) { return abi.encode(defaultAppConfig[_remoteChainId].outboundProofType); } return abi.encode(uaConfig.outboundProofType); } else if (_configType == CONFIG_TYPE_OUTBOUND_BLOCK_CONFIRMATIONS) { if (uaConfig.outboundBlockConfirmations == 0) { return abi.encode(defaultAppConfig[_remoteChainId].outboundBlockConfirmations); } return abi.encode(uaConfig.outboundBlockConfirmations); } else if (_configType == CONFIG_TYPE_ORACLE) { if (uaConfig.oracle == address(0x0)) { return abi.encode(defaultAppConfig[_remoteChainId].oracle); } return abi.encode(uaConfig.oracle); } else { revert("LayerZero: Invalid config type"); } } // returns the native fee the UA pays to cover fees function estimateFees( uint16 _dstChainId, address _ua, bytes calldata _payload, bool _payInZRO, bytes calldata _adapterParams ) external view override returns (uint nativeFee, uint zroFee) { ApplicationConfiguration memory uaConfig = _getAppConfig(_dstChainId, _ua); // Relayer Fee bytes memory adapterParams; if (_adapterParams.length > 0) { adapterParams = _adapterParams; } else { adapterParams = defaultAdapterParams[_dstChainId][uaConfig.outboundProofType]; } uint relayerFee = ILayerZeroRelayerV2(uaConfig.relayer).getFee( _dstChainId, uaConfig.outboundProofType, _ua, _payload.length, adapterParams ); // Oracle Fee address ua = _ua; // stack too deep uint oracleFee = ILayerZeroOracleV2(uaConfig.oracle).getFee( _dstChainId, uaConfig.outboundProofType, uaConfig.outboundBlockConfirmations, ua ); // LayerZero Fee uint protocolFee = treasuryContract.getFees(_payInZRO, relayerFee, oracleFee); _payInZRO ? zroFee = protocolFee : nativeFee = protocolFee; // return the sum of fees nativeFee = nativeFee.add(relayerFee).add(oracleFee); } //--------------------------------------------------------------------------- // Claim Fees // universal withdraw ZRO token function function withdrawZRO(address _to, uint _amount) external override nonReentrant { require(msg.sender == address(treasuryContract), "LayerZero: only treasury"); treasuryZROFees = treasuryZROFees.sub(_amount); layerZeroToken.safeTransfer(_to, _amount); emit WithdrawZRO(msg.sender, _to, _amount); } // universal withdraw native token function. // the source contract should perform all the authentication control function withdrawNative(address payable _to, uint _amount) external override nonReentrant { require(_to != address(0x0), "LayerZero: _to cannot be zero address"); nativeFees[msg.sender] = nativeFees[msg.sender].sub(_amount); (bool success, ) = _to.call{value: _amount}(""); require(success, "LayerZero: withdraw failed"); emit WithdrawNative(msg.sender, _to, _amount); } //--------------------------------------------------------------------------- // Owner calls, configuration only. function setLayerZeroToken(address _layerZeroToken) external onlyOwner { require(_layerZeroToken != address(0x0), "LayerZero: _layerZeroToken cannot be zero address"); layerZeroToken = IERC20(_layerZeroToken); emit SetLayerZeroToken(_layerZeroToken); } function setTreasury(address _treasury) external onlyOwner { require(_treasury != address(0x0), "LayerZero: treasury cannot be zero address"); treasuryContract = ILayerZeroTreasury(_treasury); emit SetTreasury(_treasury); } function addInboundProofLibraryForChain(uint16 _chainId, address _library) external onlyOwner { require(_library != address(0x0), "LayerZero: library cannot be zero address"); uint16 libId = maxInboundProofLibrary[_chainId]; require(libId < 65535, "LayerZero: can not add new library"); maxInboundProofLibrary[_chainId] = ++libId; inboundProofLibrary[_chainId][libId] = _library; emit AddInboundProofLibraryForChain(_chainId, _library); } function enableSupportedOutboundProof(uint16 _chainId, uint16 _proofType) external onlyOwner { supportedOutboundProof[_chainId][_proofType] = true; emit EnableSupportedOutboundProof(_chainId, _proofType); } function setDefaultConfigForChainId( uint16 _chainId, uint16 _inboundProofLibraryVersion, uint64 _inboundBlockConfirmations, address _relayer, uint16 _outboundProofType, uint64 _outboundBlockConfirmations, address _oracle ) external onlyOwner { require( _inboundProofLibraryVersion <= maxInboundProofLibrary[_chainId] && _inboundProofLibraryVersion > 0, "LayerZero: invalid inbound proof library version" ); require(_inboundBlockConfirmations > 0, "LayerZero: invalid inbound block confirmation"); require(_relayer != address(0x0), "LayerZero: invalid relayer address"); require(supportedOutboundProof[_chainId][_outboundProofType], "LayerZero: invalid outbound proof type"); require(_outboundBlockConfirmations > 0, "LayerZero: invalid outbound block confirmation"); require(_oracle != address(0x0), "LayerZero: invalid oracle address"); defaultAppConfig[_chainId] = ApplicationConfiguration( _inboundProofLibraryVersion, _inboundBlockConfirmations, _relayer, _outboundProofType, _outboundBlockConfirmations, _oracle ); emit SetDefaultConfigForChainId( _chainId, _inboundProofLibraryVersion, _inboundBlockConfirmations, _relayer, _outboundProofType, _outboundBlockConfirmations, _oracle ); } function setDefaultAdapterParamsForChainId( uint16 _chainId, uint16 _proofType, bytes calldata _adapterParams ) external onlyOwner { defaultAdapterParams[_chainId][_proofType] = _adapterParams; emit SetDefaultAdapterParamsForChainId(_chainId, _proofType, _adapterParams); } function setRemoteUln(uint16 _remoteChainId, bytes32 _remoteUln) external onlyOwner { require(ulnLookup[_remoteChainId] == bytes32(0), "LayerZero: remote uln already set"); ulnLookup[_remoteChainId] = _remoteUln; emit SetRemoteUln(_remoteChainId, _remoteUln); } function setChainAddressSize(uint16 _chainId, uint _size) external onlyOwner { require(chainAddressSizeMap[_chainId] == 0, "LayerZero: remote chain address size already set"); chainAddressSizeMap[_chainId] = _size; emit SetChainAddressSize(_chainId, _size); } //---------------------------------------------------------------------------------- // view functions function accruedNativeFee(address _address) external view override returns (uint) { return nativeFees[_address]; } function getOutboundNonce(uint16 _chainId, bytes calldata _path) external view override returns (uint64) { return nonceContract.outboundNonce(_chainId, _path); } function _isContract(address addr) internal view returns (bool) { uint size; assembly { size := extcodesize(addr) } return size != 0; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion(uint16 _version) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion(uint16 _version) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroMessagingLibrary { // send(), messages will be inflight. function send( address _userApplication, uint64 _lastNonce, uint16 _chainId, bytes calldata _destination, bytes calldata _payload, address payable refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams ) external payable; // estimate native fee at the send side function estimateFees( uint16 _chainId, address _userApplication, bytes calldata _payload, bool _payInZRO, bytes calldata _adapterParam ) external view returns (uint nativeFee, uint zroFee); //--------------------------------------------------------------------------- // setConfig / getConfig are User Application (UA) functions to specify Oracle, Relayer, blockConfirmations, libraryVersion function setConfig(uint16 _chainId, address _userApplication, uint _configType, bytes calldata _config) external; function getConfig( uint16 _chainId, address _userApplication, uint _configType ) external view returns (bytes memory); }
// SPDX-License-Identifier: BUSL-1.1 // https://github.com/ensdomains/buffer pragma solidity ^0.7.0; /** * @dev A library for working with mutable byte buffers in Solidity. * * Byte buffers are mutable and expandable, and provide a variety of primitives * for writing to them. At any time you can fetch a bytes object containing the * current contents of the buffer. The bytes object should not be stored between * operations, as it may change due to resizing of the buffer. */ library Buffer { /** * @dev Represents a mutable buffer. Buffers have a current value (buf) and * a capacity. The capacity may be longer than the current value, in * which case it can be extended without the need to allocate more memory. */ struct buffer { bytes buf; uint capacity; } /** * @dev Initializes a buffer with an initial capacity.a co * @param buf The buffer to initialize. * @param capacity The number of bytes of space to allocate the buffer. * @return The buffer, for chaining. */ function init(buffer memory buf, uint capacity) internal pure returns (buffer memory) { if (capacity % 32 != 0) { capacity += 32 - (capacity % 32); } // Allocate space for the buffer data buf.capacity = capacity; assembly { let ptr := mload(0x40) mstore(buf, ptr) mstore(ptr, 0) mstore(0x40, add(32, add(ptr, capacity))) } return buf; } /** * @dev Writes a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param off The start offset to write to. * @param rawData The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function writeRawBytes( buffer memory buf, uint off, bytes memory rawData, uint offData, uint len ) internal pure returns (buffer memory) { if (off + len > buf.capacity) { resize(buf, max(buf.capacity, len + off) * 2); } uint dest; uint src; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Start address = buffer address + offset + sizeof(buffer length) dest := add(add(bufptr, 32), off) // Update buffer length if we're extending it if gt(add(len, off), buflen) { mstore(bufptr, add(len, off)) } src := add(rawData, offData) } // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes uint mask = 256 ** (32 - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } return buf; } /** * @dev Writes a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param off The start offset to write to. * @param data The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function write(buffer memory buf, uint off, bytes memory data, uint len) internal pure returns (buffer memory) { require(len <= data.length); if (off + len > buf.capacity) { resize(buf, max(buf.capacity, len + off) * 2); } uint dest; uint src; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Start address = buffer address + offset + sizeof(buffer length) dest := add(add(bufptr, 32), off) // Update buffer length if we're extending it if gt(add(len, off), buflen) { mstore(bufptr, add(len, off)) } src := add(data, 32) } // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes uint mask = 256 ** (32 - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } return buf; } function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, data.length); } function resize(buffer memory buf, uint capacity) private pure { bytes memory oldbuf = buf.buf; init(buf, capacity); append(buf, oldbuf); } function max(uint a, uint b) private pure returns (uint) { if (a > b) { return a; } return b; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; import "./Buffer.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; library LayerZeroPacket { using Buffer for Buffer.buffer; using SafeMath for uint; struct Packet { uint16 srcChainId; uint16 dstChainId; uint64 nonce; address dstAddress; bytes srcAddress; bytes32 ulnAddress; bytes payload; } function getPacket( bytes memory data, uint16 srcChain, uint sizeOfSrcAddress, bytes32 ulnAddress ) internal pure returns (LayerZeroPacket.Packet memory) { uint16 dstChainId; address dstAddress; uint size; uint64 nonce; // The log consists of the destination chain id and then a bytes payload // 0--------------------------------------------31 // 0 | total bytes size // 32 | destination chain id // 64 | bytes offset // 96 | bytes array size // 128 | payload assembly { dstChainId := mload(add(data, 32)) size := mload(add(data, 96)) /// size of the byte array nonce := mload(add(data, 104)) // offset to convert to uint64 128 is index -24 dstAddress := mload(add(data, sub(add(128, sizeOfSrcAddress), 4))) // offset to convert to address 12 -8 } Buffer.buffer memory srcAddressBuffer; srcAddressBuffer.init(sizeOfSrcAddress); srcAddressBuffer.writeRawBytes(0, data, 136, sizeOfSrcAddress); // 128 + 8 uint payloadSize = size.sub(28).sub(sizeOfSrcAddress); Buffer.buffer memory payloadBuffer; payloadBuffer.init(payloadSize); payloadBuffer.writeRawBytes(0, data, sizeOfSrcAddress.add(156), payloadSize); // 148 + 8 return LayerZeroPacket.Packet( srcChain, dstChainId, nonce, dstAddress, srcAddressBuffer.buf, ulnAddress, payloadBuffer.buf ); } function getPacketV2( bytes memory data, uint sizeOfSrcAddress, bytes32 ulnAddress ) internal pure returns (LayerZeroPacket.Packet memory) { // packet def: abi.encodePacked(nonce, srcChain, srcAddress, dstChain, dstAddress, payload); // data def: abi.encode(packet) = offset(32) + length(32) + packet // if from EVM // 0 - 31 0 - 31 | total bytes size // 32 - 63 32 - 63 | location // 64 - 95 64 - 95 | size of the packet // 96 - 103 96 - 103 | nonce // 104 - 105 104 - 105 | srcChainId // 106 - P 106 - 125 | srcAddress, where P = 106 + sizeOfSrcAddress - 1, // P+1 - P+2 126 - 127 | dstChainId // P+3 - P+22 128 - 147 | dstAddress // P+23 - END 148 - END | payload // decode the packet uint256 realSize; uint64 nonce; uint16 srcChain; uint16 dstChain; address dstAddress; assembly { realSize := mload(add(data, 64)) nonce := mload(add(data, 72)) // 104 - 32 srcChain := mload(add(data, 74)) // 106 - 32 dstChain := mload(add(data, add(76, sizeOfSrcAddress))) // P + 3 - 32 = 105 + size + 3 - 32 = 76 + size dstAddress := mload(add(data, add(96, sizeOfSrcAddress))) // P + 23 - 32 = 105 + size + 23 - 32 = 96 + size } require(srcChain != 0, "LayerZeroPacket: invalid packet"); Buffer.buffer memory srcAddressBuffer; srcAddressBuffer.init(sizeOfSrcAddress); srcAddressBuffer.writeRawBytes(0, data, 106, sizeOfSrcAddress); uint nonPayloadSize = sizeOfSrcAddress.add(32); // 2 + 2 + 8 + 20, 32 + 20 = 52 if sizeOfSrcAddress == 20 uint payloadSize = realSize.sub(nonPayloadSize); Buffer.buffer memory payloadBuffer; payloadBuffer.init(payloadSize); payloadBuffer.writeRawBytes(0, data, nonPayloadSize.add(96), payloadSize); return LayerZeroPacket.Packet( srcChain, dstChain, nonce, dstAddress, srcAddressBuffer.buf, ulnAddress, payloadBuffer.buf ); } function getPacketV3( bytes memory data, uint sizeOfSrcAddress, bytes32 ulnAddress ) internal pure returns (LayerZeroPacket.Packet memory) { // data def: abi.encodePacked(nonce, srcChain, srcAddress, dstChain, dstAddress, payload); // if from EVM // 0 - 31 0 - 31 | total bytes size // 32 - 39 32 - 39 | nonce // 40 - 41 40 - 41 | srcChainId // 42 - P 42 - 61 | srcAddress, where P = 41 + sizeOfSrcAddress, // P+1 - P+2 62 - 63 | dstChainId // P+3 - P+22 64 - 83 | dstAddress // P+23 - END 84 - END | payload // decode the packet uint256 realSize = data.length; uint nonPayloadSize = sizeOfSrcAddress.add(32); // 2 + 2 + 8 + 20, 32 + 20 = 52 if sizeOfSrcAddress == 20 require(realSize >= nonPayloadSize, "LayerZeroPacket: invalid packet"); uint payloadSize = realSize - nonPayloadSize; uint64 nonce; uint16 srcChain; uint16 dstChain; address dstAddress; assembly { nonce := mload(add(data, 8)) // 40 - 32 srcChain := mload(add(data, 10)) // 42 - 32 dstChain := mload(add(data, add(12, sizeOfSrcAddress))) // P + 3 - 32 = 41 + size + 3 - 32 = 12 + size dstAddress := mload(add(data, add(32, sizeOfSrcAddress))) // P + 23 - 32 = 41 + size + 23 - 32 = 32 + size } require(srcChain != 0, "LayerZeroPacket: invalid packet"); Buffer.buffer memory srcAddressBuffer; srcAddressBuffer.init(sizeOfSrcAddress); srcAddressBuffer.writeRawBytes(0, data, 42, sizeOfSrcAddress); Buffer.buffer memory payloadBuffer; if (payloadSize > 0) { payloadBuffer.init(payloadSize); payloadBuffer.writeRawBytes(0, data, nonPayloadSize.add(32), payloadSize); } return LayerZeroPacket.Packet( srcChain, dstChain, nonce, dstAddress, srcAddressBuffer.buf, ulnAddress, payloadBuffer.buf ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @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://diligence.consensys.net/posts/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.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @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, it is bubbled up by this * function (like regular Solidity function calls). * * 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. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @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`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // 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 // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "./IERC20.sol"; import "../../math/SafeMath.sol"; import "../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.0; pragma abicoder v2; import "../proof/utility/LayerZeroPacket.sol"; interface ILayerZeroValidationLibrary { function validateProof( bytes32 blockData, bytes calldata _data, uint _remoteAddressSize ) external returns (LayerZeroPacket.Packet memory packet); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; interface ILayerZeroTreasury { function getFees(bool payInZro, uint relayerFee, uint oracleFee) external view returns (uint); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send( uint16 _dstChainId, bytes calldata _destination, bytes calldata _payload, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams ) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload( uint16 _srcChainId, bytes calldata _srcAddress, address _dstAddress, uint64 _nonce, uint _gasLimit, bytes calldata _payload ) external; // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees( uint16 _dstChainId, address _userApplication, bytes calldata _payload, bool _payInZRO, bytes calldata _adapterParam ) external view returns (uint nativeFee, uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress(address _userApplication) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress(address _userApplication) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig( uint16 _version, uint16 _chainId, address _userApplication, uint _configType ) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion(address _userApplication) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion(address _userApplication) external view returns (uint16); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.0; import "./ILayerZeroUserApplicationConfig.sol"; import "./ILayerZeroMessagingLibrary.sol"; interface ILayerZeroMessagingLibraryV2 is ILayerZeroMessagingLibrary { function getOutboundNonce(uint16 _chainId, bytes calldata _path) external view returns (uint64); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.0; interface ILayerZeroOracleV2 { // @notice query price and assign jobs at the same time // @param _dstChainId - the destination endpoint identifier // @param _outboundProofType - the proof type identifier to specify proof to be relayed // @param _outboundBlockConfirmation - block confirmation delay before relaying blocks // @param _userApplication - the source sending contract address function assignJob( uint16 _dstChainId, uint16 _outboundProofType, uint64 _outboundBlockConfirmation, address _userApplication ) external returns (uint price); // @notice query the oracle price for relaying block information to the destination chain // @param _dstChainId the destination endpoint identifier // @param _outboundProofType the proof type identifier to specify the data to be relayed // @param _outboundBlockConfirmation - block confirmation delay before relaying blocks // @param _userApplication - the source sending contract address function getFee( uint16 _dstChainId, uint16 _outboundProofType, uint64 _outboundBlockConfirmation, address _userApplication ) external view returns (uint price); // @notice withdraw the accrued fee in ultra light node // @param _to - the fee receiver // @param _amount - the withdrawal amount function withdrawFee(address payable _to, uint _amount) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.0; pragma abicoder v2; interface ILayerZeroUltraLightNodeV2 { // Relayer functions function validateTransactionProof( uint16 _srcChainId, address _dstAddress, uint _gasLimit, bytes32 _lookupHash, bytes32 _blockData, bytes calldata _transactionProof ) external; // an Oracle delivers the block data using updateHash() function updateHash(uint16 _srcChainId, bytes32 _lookupHash, uint _confirmations, bytes32 _blockData) external; // can only withdraw the receivable of the msg.sender function withdrawNative(address payable _to, uint _amount) external; function withdrawZRO(address _to, uint _amount) external; // view functions function getAppConfig( uint16 _remoteChainId, address _userApplicationAddress ) external view returns (ApplicationConfiguration memory); function accruedNativeFee(address _address) external view returns (uint); struct ApplicationConfiguration { uint16 inboundProofLibraryVersion; uint64 inboundBlockConfirmations; address relayer; uint16 outboundProofType; uint64 outboundBlockConfirmations; address oracle; } event HashReceived( uint16 indexed srcChainId, address indexed oracle, bytes32 lookupHash, bytes32 blockData, uint confirmations ); event RelayerParams(bytes adapterParams, uint16 outboundProofType); event Packet(bytes payload); event InvalidDst( uint16 indexed srcChainId, bytes srcAddress, address indexed dstAddress, uint64 nonce, bytes32 payloadHash ); event PacketReceived( uint16 indexed srcChainId, bytes srcAddress, address indexed dstAddress, uint64 nonce, bytes32 payloadHash ); event AppConfigUpdated(address indexed userApplication, uint indexed configType, bytes newConfig); event AddInboundProofLibraryForChain(uint16 indexed chainId, address lib); event EnableSupportedOutboundProof(uint16 indexed chainId, uint16 proofType); event SetChainAddressSize(uint16 indexed chainId, uint size); event SetDefaultConfigForChainId( uint16 indexed chainId, uint16 inboundProofLib, uint64 inboundBlockConfirm, address relayer, uint16 outboundProofType, uint64 outboundBlockConfirm, address oracle ); event SetDefaultAdapterParamsForChainId(uint16 indexed chainId, uint16 indexed proofType, bytes adapterParams); event SetLayerZeroToken(address indexed tokenAddress); event SetRemoteUln(uint16 indexed chainId, bytes32 uln); event SetTreasury(address indexed treasuryAddress); event WithdrawZRO(address indexed msgSender, address indexed to, uint amount); event WithdrawNative(address indexed msgSender, address indexed to, uint amount); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.0; interface ILayerZeroRelayerV2 { // @notice query price and assign jobs at the same time // @param _dstChainId - the destination endpoint identifier // @param _outboundProofType - the proof type identifier to specify proof to be relayed // @param _userApplication - the source sending contract address. relayers may apply price discrimination to user apps // @param _payloadSize - the length of the payload. it is an indicator of gas usage for relaying cross-chain messages // @param _adapterParams - optional parameters for extra service plugins, e.g. sending dust tokens at the destination chain function assignJob( uint16 _dstChainId, uint16 _outboundProofType, address _userApplication, uint _payloadSize, bytes calldata _adapterParams ) external returns (uint price); // @notice query the relayer price for relaying the payload and its proof to the destination chain // @param _dstChainId - the destination endpoint identifier // @param _outboundProofType - the proof type identifier to specify proof to be relayed // @param _userApplication - the source sending contract address. relayers may apply price discrimination to user apps // @param _payloadSize - the length of the payload. it is an indicator of gas usage for relaying cross-chain messages // @param _adapterParams - optional parameters for extra service plugins, e.g. sending dust tokens at the destination chain function getFee( uint16 _dstChainId, uint16 _outboundProofType, address _userApplication, uint _payloadSize, bytes calldata _adapterParams ) external view returns (uint price); // @notice withdraw the accrued fee in ultra light node // @param _to - the fee receiver // @param _amount - the withdrawal amount function withdrawFee(address payable _to, uint _amount) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; import "./interfaces/ILayerZeroEndpoint.sol"; contract NonceContract { ILayerZeroEndpoint public immutable endpoint; // outboundNonce = [dstChainId][remoteAddress + localAddress] mapping(uint16 => mapping(bytes => uint64)) public outboundNonce; constructor(address _endpoint) { endpoint = ILayerZeroEndpoint(_endpoint); } function increment(uint16 _chainId, address _ua, bytes calldata _path) external returns (uint64) { require( endpoint.getSendLibraryAddress(_ua) == msg.sender, "NonceContract: msg.sender is not valid sendlibrary" ); return ++outboundNonce[_chainId][_path]; } }
{ "optimizer": { "enabled": true, "runs": 10000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_endpoint","type":"address"},{"internalType":"address","name":"_nonceContract","type":"address"},{"internalType":"uint16","name":"_localChainId","type":"uint16"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"address","name":"lib","type":"address"}],"name":"AddInboundProofLibraryForChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userApplication","type":"address"},{"indexed":true,"internalType":"uint256","name":"configType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newConfig","type":"bytes"}],"name":"AppConfigUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"proofType","type":"uint16"}],"name":"EnableSupportedOutboundProof","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"srcChainId","type":"uint16"},{"indexed":true,"internalType":"address","name":"oracle","type":"address"},{"indexed":false,"internalType":"bytes32","name":"lookupHash","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"blockData","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"confirmations","type":"uint256"}],"name":"HashReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":true,"internalType":"address","name":"dstAddress","type":"address"},{"indexed":false,"internalType":"uint64","name":"nonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"payloadHash","type":"bytes32"}],"name":"InvalidDst","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"payload","type":"bytes"}],"name":"Packet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":true,"internalType":"address","name":"dstAddress","type":"address"},{"indexed":false,"internalType":"uint64","name":"nonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"payloadHash","type":"bytes32"}],"name":"PacketReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"adapterParams","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"outboundProofType","type":"uint16"}],"name":"RelayerParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"size","type":"uint256"}],"name":"SetChainAddressSize","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":true,"internalType":"uint16","name":"proofType","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"adapterParams","type":"bytes"}],"name":"SetDefaultAdapterParamsForChainId","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"inboundProofLib","type":"uint16"},{"indexed":false,"internalType":"uint64","name":"inboundBlockConfirm","type":"uint64"},{"indexed":false,"internalType":"address","name":"relayer","type":"address"},{"indexed":false,"internalType":"uint16","name":"outboundProofType","type":"uint16"},{"indexed":false,"internalType":"uint64","name":"outboundBlockConfirm","type":"uint64"},{"indexed":false,"internalType":"address","name":"oracle","type":"address"}],"name":"SetDefaultConfigForChainId","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"}],"name":"SetLayerZeroToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"bytes32","name":"uln","type":"bytes32"}],"name":"SetRemoteUln","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"treasuryAddress","type":"address"}],"name":"SetTreasury","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"msgSender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawNative","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"msgSender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawZRO","type":"event"},{"inputs":[],"name":"CONFIG_TYPE_INBOUND_BLOCK_CONFIRMATIONS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONFIG_TYPE_INBOUND_PROOF_LIBRARY_VERSION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONFIG_TYPE_ORACLE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONFIG_TYPE_OUTBOUND_BLOCK_CONFIRMATIONS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONFIG_TYPE_OUTBOUND_PROOF_TYPE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONFIG_TYPE_RELAYER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"accruedNativeFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"address","name":"_library","type":"address"}],"name":"addInboundProofLibraryForChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"appConfig","outputs":[{"internalType":"uint16","name":"inboundProofLibraryVersion","type":"uint16"},{"internalType":"uint64","name":"inboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"relayer","type":"address"},{"internalType":"uint16","name":"outboundProofType","type":"uint16"},{"internalType":"uint64","name":"outboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"oracle","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"chainAddressSizeMap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"defaultAdapterParams","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"defaultAppConfig","outputs":[{"internalType":"uint16","name":"inboundProofLibraryVersion","type":"uint16"},{"internalType":"uint64","name":"inboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"relayer","type":"address"},{"internalType":"uint16","name":"outboundProofType","type":"uint16"},{"internalType":"uint64","name":"outboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"oracle","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint16","name":"_proofType","type":"uint16"}],"name":"enableSupportedOutboundProof","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endpoint","outputs":[{"internalType":"contract ILayerZeroEndpoint","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"address","name":"_ua","type":"address"},{"internalType":"bytes","name":"_payload","type":"bytes"},{"internalType":"bool","name":"_payInZRO","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateFees","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"address","name":"_ua","type":"address"}],"name":"getAppConfig","outputs":[{"components":[{"internalType":"uint16","name":"inboundProofLibraryVersion","type":"uint16"},{"internalType":"uint64","name":"inboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"relayer","type":"address"},{"internalType":"uint16","name":"outboundProofType","type":"uint16"},{"internalType":"uint64","name":"outboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"oracle","type":"address"}],"internalType":"struct ILayerZeroUltraLightNodeV2.ApplicationConfiguration","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"address","name":"_ua","type":"address"},{"internalType":"uint256","name":"_configType","type":"uint256"}],"name":"getConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"bytes","name":"_path","type":"bytes"}],"name":"getOutboundNonce","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"hashLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"inboundProofLibrary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"layerZeroToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"localChainId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"maxInboundProofLibrary","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nativeFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonceContract","outputs":[{"internalType":"contract NonceContract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ua","type":"address"},{"internalType":"uint64","name":"","type":"uint64"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_path","type":"bytes"},{"internalType":"bytes","name":"_payload","type":"bytes"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"send","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"_size","type":"uint256"}],"name":"setChainAddressSize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"address","name":"_ua","type":"address"},{"internalType":"uint256","name":"_configType","type":"uint256"},{"internalType":"bytes","name":"_config","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint16","name":"_proofType","type":"uint16"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"setDefaultAdapterParamsForChainId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint16","name":"_inboundProofLibraryVersion","type":"uint16"},{"internalType":"uint64","name":"_inboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"_relayer","type":"address"},{"internalType":"uint16","name":"_outboundProofType","type":"uint16"},{"internalType":"uint64","name":"_outboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"_oracle","type":"address"}],"name":"setDefaultConfigForChainId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_layerZeroToken","type":"address"}],"name":"setLayerZeroToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"bytes32","name":"_remoteUln","type":"bytes32"}],"name":"setRemoteUln","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"supportedOutboundProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasuryContract","outputs":[{"internalType":"contract ILayerZeroTreasury","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryZROFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"ulnLookup","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes32","name":"_lookupHash","type":"bytes32"},{"internalType":"uint256","name":"_confirmations","type":"uint256"},{"internalType":"bytes32","name":"_blockData","type":"bytes32"}],"name":"updateHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"address","name":"_dstAddress","type":"address"},{"internalType":"uint256","name":"_gasLimit","type":"uint256"},{"internalType":"bytes32","name":"_lookupHash","type":"bytes32"},{"internalType":"bytes32","name":"_blockData","type":"bytes32"},{"internalType":"bytes","name":"_transactionProof","type":"bytes"}],"name":"validateTransactionProof","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawNative","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawZRO","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e06040523480156200001157600080fd5b50604051620055423803806200554283398101604081905262000034916200013f565b60016000908155620000456200011e565b600180546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001600160a01b038316620000c55760405162461bcd60e51b8152600401620000bc9062000191565b60405180910390fd5b6001600160a01b038216620000ee5760405162461bcd60e51b8152600401620000bc90620001db565b60f01b6001600160f01b03191660a052606091821b6001600160601b0319908116608052911b1660c0526200022a565b3390565b80516001600160a01b03811681146200013a57600080fd5b919050565b60008060006060848603121562000154578283fd5b6200015f8462000122565b92506200016f6020850162000122565b9150604084015161ffff8116811462000186578182fd5b809150509250925092565b6020808252602a908201527f4c617965725a65726f3a20656e64706f696e742063616e6e6f74206265207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602f908201527f4c617965725a65726f3a206e6f6e6365436f6e74726163742063616e6e6f742060408201526e6265207a65726f206164647265737360881b606082015260800190565b60805160601c60a05160f01c60c05160601c6152bf620002836000398061084d5280611045528061267852508061124f528061175052806123ef525080610e9e5280611774528061257c5280612c0c52506152bf6000f3fe6080604052600436106102e75760003560e01c80638317814a11610184578063d543c774116100d6578063ed28580a1161008a578063f47a5feb11610064578063f47a5feb146107f6578063f58589a21461080b578063f8e1734c1461082b576102e7565b8063ed28580a14610796578063f0f44260146107b6578063f2fde38b146107d6576102e7565b8063ddfdef5a116100bb578063ddfdef5a14610736578063ea216c2114610756578063eb0d4c3114610776576102e7565b8063d543c774146106e9578063db00719b14610716576102e7565b8063959f594311610138578063b77d22ad11610112578063b77d22ad14610687578063b8e7e3e01461069c578063b9a99bed146106bc576102e7565b8063959f59431461061a578063987fa2d51461063a578063a46622221461065a576102e7565b806387078f9f1161016957806387078f9f146105d05780638da5cb5b146105f0578063904d3b8d14610605576102e7565b80638317814a146105905780638525b711146105b0576102e7565b806352d2871f1161023d5780636a14ac82116101f1578063759c5b3b116101cb578063759c5b3b1461053b5780638140666e1461055b5780638207f79d14610570576102e7565b80636a14ac82146104e6578063704316e514610506578063715018a614610526576102e7565b80635b056da5116102225780635b056da51461048f5780635e280f11146104b157806369412bfa146104c6576102e7565b806352d2871f1461044f57806352d3b5001461046f576102e7565b80632cfacb061161029f57806340a7bb101161027957806340a7bb10146103f957806349148c37146104275780634d3a0f7c1461043c576102e7565b80632cfacb06146103905780632f813464146103b257806331bd2430146103e4576102e7565b806307b9ca7c116102d057806307b9ca7c1461033957806318da00111461034e5780632a819bbf14610363576102e7565b806302bd9743146102ec57806307b18bde14610317575b600080fd5b3480156102f857600080fd5b5061030161084b565b60405161030e919061448c565b60405180910390f35b34801561032357600080fd5b50610337610332366004613c3a565b61086f565b005b34801561034557600080fd5b506103016109f9565b34801561035a57600080fd5b50610301610a08565b34801561036f57600080fd5b5061038361037e366004614180565b610a17565b60405161030e9190614521565b34801561039c57600080fd5b506103a5610ad9565b60405161030e91906144c3565b3480156103be57600080fd5b506103d26103cd366004613ec0565b610ade565b60405161030e96959493929190615117565b3480156103f057600080fd5b506103a5610b62565b34801561040557600080fd5b50610419610414366004613f09565b610b67565b60405161030e929190615160565b34801561043357600080fd5b506103a5610e97565b61033761044a366004613cf4565b610e9c565b34801561045b57600080fd5b5061038361046a366004613fb4565b6112e8565b34801561047b57600080fd5b5061033761048a366004613c1e565b611652565b34801561049b57600080fd5b506104a461174e565b60405161030e9190614fe2565b3480156104bd57600080fd5b50610301611772565b3480156104d257600080fd5b506103a56104e1366004613c1e565b611796565b3480156104f257600080fd5b50610337610501366004614200565b6117b5565b34801561051257600080fd5b506103376105213660046140f3565b611b17565b34801561053257600080fd5b50610337611bdc565b34801561054757600080fd5b506103a5610556366004613c9d565b611cb2565b34801561056757600080fd5b506103a5611cde565b34801561057c57600080fd5b5061033761058b366004613edc565b611ce3565b34801561059c57600080fd5b506103376105ab36600461419d565b611e7c565b3480156105bc57600080fd5b506103376105cb366004613ce2565b611f65565b3480156105dc57600080fd5b506103376105eb3660046140d6565b612067565b3480156105fc57600080fd5b5061030161215e565b34801561061157600080fd5b506103a561216d565b34801561062657600080fd5b506103a5610635366004613ec0565b612172565b34801561064657600080fd5b50610337610655366004613ff4565b612184565b34801561066657600080fd5b5061067a610675366004613edc565b612618565b60405161030e9190614f76565b34801561069357600080fd5b506103a561262a565b3480156106a857600080fd5b506104a46106b7366004613ec0565b61262f565b3480156106c857600080fd5b506106dc6106d736600461412d565b612645565b60405161030e919061516e565b3480156106f557600080fd5b50610709610704366004614180565b612709565b60405161030e91906144a0565b34801561072257600080fd5b50610301610731366004614180565b612729565b34801561074257600080fd5b506103d2610751366004613c65565b61274f565b34801561076257600080fd5b506103a5610771366004613ec0565b6127de565b34801561078257600080fd5b50610337610791366004614180565b6127f0565b3480156107a257600080fd5b506103376107b13660046140d6565b6128de565b3480156107c257600080fd5b506103376107d1366004613c1e565b6129c9565b3480156107e257600080fd5b506103376107f1366004613c1e565b612ac5565b34801561080257600080fd5b506103a5612bf2565b34801561081757600080fd5b506103a5610826366004613c1e565b612bf8565b34801561083757600080fd5b50610337610846366004614065565b612c0a565b7f000000000000000000000000000000000000000000000000000000000000000081565b600260005414156108c7576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556001600160a01b0382166108fb5760405162461bcd60e51b81526004016108f290614745565b60405180910390fd5b336000908152600460205260409020546109159082612f71565b336000908152600460205260408082209290925590516001600160a01b038416908390610941906143c1565b60006040518083038185875af1925050503d806000811461097e576040519150601f19603f3d011682016040523d82523d6000602084013e610983565b606091505b50509050806109a45760405162461bcd60e51b81526004016108f2906146b1565b826001600160a01b0316336001600160a01b03167f3bfd26201736b5cb14a562ab3cfc2bef76901726e3a78483d6288af47131e1d9846040516109e791906144c3565b60405180910390a35050600160005550565b6002546001600160a01b031681565b6003546001600160a01b031681565b60086020908152600092835260408084208252918352918190208054825160026001831615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190921691909104601f810185900485028201850190935282815292909190830182828015610ad15780601f10610aa657610100808354040283529160200191610ad1565b820191906000526020600020905b815481529060010190602001808311610ab457829003601f168201915b505050505081565b600381565b6007602052600090815260409020805460019091015461ffff8083169267ffffffffffffffff6201000082048116936001600160a01b036a010000000000000000000084048116947e010000000000000000000000000000000000000000000000000000000000009094049093169291811691680100000000000000009091041686565b600681565b6000806000610b768a8a612fce565b905060608415610bbf5785858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929350610c8e92505050565b61ffff808c166000908152600860209081526040808320606087015190941683529281529082902080548351601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018616150201909316929092049182018490048402810184019094528084529091830182828015610c865780601f10610c5b57610100808354040283529160200191610c86565b820191906000526020600020905b815481529060010190602001808311610c6957829003601f168201915b505050505090505b600082604001516001600160a01b031663c03f15298d85606001518e8e8e9050876040518663ffffffff1660e01b8152600401610ccf9594939291906150a5565b60206040518083038186803b158015610ce757600080fd5b505afa158015610cfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1f9190614295565b905060008b905060008460a001516001600160a01b0316635553fb8e8f87606001518860800151866040518563ffffffff1660e01b8152600401610d6694939291906150e1565b60206040518083038186803b158015610d7e57600080fd5b505afa158015610d92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db69190614295565b6003546040517f5cbbbd750000000000000000000000000000000000000000000000000000000081529192506000916001600160a01b0390911690635cbbbd7590610e09908e90889087906004016144ab565b60206040518083038186803b158015610e2157600080fd5b505afa158015610e35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e599190614295565b90508a610e695780975087610e6e565b809650865b50610e8382610e7d8a87613199565b90613199565b975050505050505097509795505050505050565b600281565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163314610ee45760405162461bcd60e51b81526004016108f290614d6e565b61ffff89166000908152600e60205260409020548b908a90610f185760405162461bcd60e51b81526004016108f2906145e6565b61ffff81166000908152600c6020526040812054606091908015801590610f415750601481018c145b610f5d5760405162461bcd60e51b81526004016108f290614e02565b6000808e8e8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505083810160140151925090506001600160a01b0387811690831614610fcc5760405162461bcd60e51b81526004016108f290614a4f565b8e8e6000908592610fdf939291906151a7565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040517f6fe7b673000000000000000000000000000000000000000000000000000000008152929750506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691636fe7b673915061107f9089908b908690600401614ff1565b602060405180830381600087803b15801561109957600080fd5b505af11580156110ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d191906142c9565b935050505060008a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093945061111d9250879150889050612fce565b9050600061116586838986518d8d8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506131f392505050565b9050600061117487848a6133cd565b9050600061118483838b8f613487565b9050600061119682610e7d8686613199565b9050348111156111b85760405162461bcd60e51b81526004016108f2906146e8565b60006111c43483612f71565b9050801561124a5760008f6001600160a01b0316826040516111e5906143c1565b60006040518083038185875af1925050503d8060008114611222576040519150601f19603f3d011682016040523d82523d6000602084013e611227565b606091505b50509050806112485760405162461bcd60e51b81526004016108f29061485c565b505b6000887f00000000000000000000000000000000000000000000000000000000000000008d8d8d8c604051602001611287969594939291906143c4565b60405160208183030381529060405290507fe9bded5f24a4168e4f3bf44e00298c993b22376aad8c58c7dda9718a54cbea82816040516112c79190614521565b60405180910390a15050505050505050505050505050505050505050505050565b6001600160a01b038216600090815260066020908152604080832061ffff871684529091529020606090600183141561137c57805461ffff166113665761ffff80861660009081526007602090815260409182902054915161134f93929092169101614fe2565b60405160208183030381529060405291505061164b565b805460405161134f9161ffff1690602001614fe2565b60028314156113f257805462010000900467ffffffffffffffff166113d05761ffff851660009081526007602090815260409182902054915161134f9262010000900467ffffffffffffffff16910161516e565b805460405161134f9162010000900467ffffffffffffffff169060200161516e565b600383141561147d5780546a010000000000000000000090046001600160a01b03166114545761ffff851660009081526007602090815260409182902054915161134f926a010000000000000000000090046001600160a01b0316910161448c565b805460405161134f916a010000000000000000000090046001600160a01b03169060200161448c565b60048314156115365780547e01000000000000000000000000000000000000000000000000000000000000900461ffff166114fe5761ffff80861660009081526007602090815260409182902054915161134f937e010000000000000000000000000000000000000000000000000000000000009093049092169101614fe2565b805460405161134f917e01000000000000000000000000000000000000000000000000000000000000900461ffff1690602001614fe2565b60058314156115a357600181015467ffffffffffffffff166115845761ffff851660009081526007602090815260409182902060010154915161134f9267ffffffffffffffff16910161516e565b600181015460405161134f9167ffffffffffffffff169060200161516e565b60068314156116315760018101546801000000000000000090046001600160a01b03166116075761ffff851660009081526007602090815260409182902060010154915161134f926801000000000000000090046001600160a01b0316910161448c565b600181015460405161134f916801000000000000000090046001600160a01b03169060200161448c565b60405162461bcd60e51b81526004016108f29061467a565b505b9392505050565b61165a6135f1565b6001600160a01b031661166b61215e565b6001600160a01b0316146116c6576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166116ec5760405162461bcd60e51b81526004016108f2906147a2565b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f33d644987381deff4408951d55afa136f124e22a7810b163b2aaa3ebef770f6490600090a250565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b6001600160a01b0381166000908152600460205260409020545b919050565b6117bd6135f1565b6001600160a01b03166117ce61215e565b6001600160a01b031614611829576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b61ffff8088166000908152600a6020526040902054811690871611801590611855575060008661ffff16115b6118715760405162461bcd60e51b81526004016108f290614b9d565b60008567ffffffffffffffff161161189b5760405162461bcd60e51b81526004016108f290614ebc565b6001600160a01b0384166118c15760405162461bcd60e51b81526004016108f2906147ff565b61ffff8088166000908152600b602090815260408083209387168352929052205460ff166119015760405162461bcd60e51b81526004016108f290614589565b60008267ffffffffffffffff161161192b5760405162461bcd60e51b81526004016108f290614da5565b6001600160a01b0381166119515760405162461bcd60e51b81526004016108f290614927565b6040518060c001604052808761ffff1681526020018667ffffffffffffffff168152602001856001600160a01b031681526020018461ffff1681526020018367ffffffffffffffff168152602001826001600160a01b0316815250600760008961ffff1661ffff16815260200190815260200160002060008201518160000160006101000a81548161ffff021916908361ffff16021790555060208201518160000160026101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550604082015181600001600a6101000a8154816001600160a01b0302191690836001600160a01b03160217905550606082015181600001601e6101000a81548161ffff021916908361ffff16021790555060808201518160010160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a08201518160010160086101000a8154816001600160a01b0302191690836001600160a01b031602179055509050508661ffff167f5a76432853a0871c4e780def7f3ffc7912339b53f022ac31127fe5ff84a36fa1878787878787604051611b0696959493929190615117565b60405180910390a250505050505050565b336000908152600d6020908152604080832061ffff8816845282528083208684528252808320848452909152902054828110611b655760405162461bcd60e51b81526004016108f290614ae3565b336000818152600d6020908152604080832061ffff8a1680855290835281842089855283528184208785529092529182902086905590517f74bbc026808dcba59692d6a8bb20596849ca718e10e2432c6cdf48af865bc5d990611bcd908890879089906144cc565b60405180910390a35050505050565b611be46135f1565b6001600160a01b0316611bf561215e565b6001600160a01b031614611c50576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b600d60209081526000948552604080862082529385528385208152918452828420909152825290205481565b600481565b611ceb6135f1565b6001600160a01b0316611cfc61215e565b6001600160a01b031614611d57576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b038116611d7d5760405162461bcd60e51b81526004016108f290614a86565b61ffff8083166000908152600a60205260409020548116908110611db35760405162461bcd60e51b81526004016108f290614d11565b61ffff8381166000818152600a6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660019790970195861696871790556009825280832095835294905283902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03861617905591519091907f802d55279d51813cb7a9a98e8fd2d7bec5346cb830901c11b85d1650cb857e9a90611e6f90859061448c565b60405180910390a2505050565b611e846135f1565b6001600160a01b0316611e9561215e565b6001600160a01b031614611ef0576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b61ffff8085166000908152600860209081526040808320938716835292905220611f1b9083836139e9565b508261ffff168461ffff167f4a5695eee2a74d548d5f5c485a3de99ace99e3b664c8e30a90f49be6ebb549328484604051611f5792919061450d565b60405180910390a350505050565b60026000541415611fbd576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556003546001600160a01b03163314611fec5760405162461bcd60e51b81526004016108f290614643565b600554611ff99082612f71565b600555600254612013906001600160a01b031683836135f5565b816001600160a01b0316336001600160a01b03167f3a20c8c3cd1848485ae8261a52398bb9b26f195b717306b3cf7f058e62c095d58360405161205691906144c3565b60405180910390a350506001600055565b61206f6135f1565b6001600160a01b031661208061215e565b6001600160a01b0316146120db576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b61ffff82166000908152600c60205260409020541561210c5760405162461bcd60e51b81526004016108f290614e5f565b61ffff82166000818152600c602052604090819020839055517f0611bb2107e385b79ec826fff8ecc1c1248a7aae3c875c96668f8cfbf1734220906121529084906144c3565b60405180910390a25050565b6001546001600160a01b031690565b600581565b600c6020526000908152604090205481565b60006121908888612fce565b60408101519091506001600160a01b031633146121bf5760405162461bcd60e51b81526004016108f290614a18565b6121c7613a93565b61ffff89166000908152600c6020526040902054806121f85760405162461bcd60e51b81526004016108f290614e02565b60a08301516001600160a01b03166000908152600d6020908152604080832061ffff8e16845282528083208a8452825280832089845290915290205480158015906122515750836020015167ffffffffffffffff168110155b61226d5760405162461bcd60e51b81526004016108f290614f19565b61ffff808c166000908152600960209081526040808320885190941683529290528190205490517fb71e0f710000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690819063b71e0f71906122df908b908b908b9089906004016144e2565b600060405180830381600087803b1580156122f957600080fd5b505af115801561230d573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526123539190810190613de4565b60a081015161ffff8e166000908152600e6020526040902054919550149150508015612382575060a082015115155b61239e5760405162461bcd60e51b81526004016108f290614984565b8961ffff16826000015161ffff16146123c95760405162461bcd60e51b81526004016108f2906149e1565b80826080015151146123ed5760405162461bcd60e51b81526004016108f290614bfa565b7f000000000000000000000000000000000000000000000000000000000000000061ffff16826020015161ffff16146124385760405162461bcd60e51b81526004016108f290614b66565b886001600160a01b031682606001516001600160a01b03161461246d5760405162461bcd60e51b81526004016108f2906148f0565b6124768961367a565b6124e75781606001516001600160a01b0316826000015161ffff167fa2786598bd84ae4a299103996359e6cb4333404583256079dfc279386baf5832846080015185604001518660c00151805190602001206040516124d79392919061455a565b60405180910390a350505061260f565b600082608001518360600151604051602001612504929190614377565b604051602081830303815290604052905082606001516001600160a01b0316836000015161ffff167f2bd2d8a84b748439fd50d79a49502b4eb5faa25b864da6a9ab5c150704be9a4d856080015186604001518760c00151805190602001206040516125729392919061455a565b60405180910390a37f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c2fa48138c838d87604001518e8960c001516040518763ffffffff1660e01b81526004016125d896959493929190615044565b600060405180830381600087803b1580156125f257600080fd5b505af1158015612606573d6000803e3d6000fd5b50505050505050505b50505050505050565b612620613ad1565b61164b8383612fce565b600181565b600a6020526000908152604090205461ffff1681565b6040517fc533338f0000000000000000000000000000000000000000000000000000000081526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c533338f906126b190879087908790600401615026565b60206040518083038186803b1580156126c957600080fd5b505afa1580156126dd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270191906142c9565b949350505050565b600b60209081526000928352604080842090915290825290205460ff1681565b60096020908152600092835260408084209091529082529020546001600160a01b031681565b60066020908152600092835260408084209091529082529020805460019091015461ffff8083169267ffffffffffffffff6201000082048116936001600160a01b036a010000000000000000000084048116947e010000000000000000000000000000000000000000000000000000000000009094049093169291811691680100000000000000009091041686565b600e6020526000908152604090205481565b6127f86135f1565b6001600160a01b031661280961215e565b6001600160a01b031614612864576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b61ffff8083166000818152600b60209081526040808320948616835293905282902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517fec23bee6f88cfecebb09d6aaaed66f0ce110debc1f61117c8270a7116597df9a90612152908490614fe2565b6128e66135f1565b6001600160a01b03166128f761215e565b6001600160a01b031614612952576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b61ffff82166000908152600e6020526040902054156129835760405162461bcd60e51b81526004016108f290614cb4565b61ffff82166000818152600e602052604090819020839055517f0dad975e1d2fbe771c95cdcc7be9a1e61181de7173abe0a32b8f8f83140873e5906121529084906144c3565b6129d16135f1565b6001600160a01b03166129e261215e565b6001600160a01b031614612a3d576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b038116612a635760405162461bcd60e51b81526004016108f290614c57565b600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517fcb7ef3e545f5cdb893f5c568ba710fe08f336375a2d9fd66e161033f8fc09ef390600090a250565b612acd6135f1565b6001600160a01b0316612ade61215e565b6001600160a01b031614612b39576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b038116612b7e5760405162461bcd60e51b815260040180806020018281038252602681526020018061523a6026913960400191505060405180910390fd5b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b60055481565b60046020526000908152604090205481565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163314612c525760405162461bcd60e51b81526004016108f290614d6e565b6001600160a01b038416600090815260066020908152604080832061ffff8916845290915290206001841415612cff576000612c9083850185613ec0565b61ffff8089166000908152600a60205260409020549192509081169082161115612ccc5760405162461bcd60e51b81526004016108f290614b9d565b81547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff91909116178155612f25565b6002841415612d56576000612d16838501856142ad565b825467ffffffffffffffff90911662010000027fffffffffffffffffffffffffffffffffffffffffffff0000000000000000ffff90911617825550612f25565b6003841415612db4576000612d6d83850185613c1e565b82546001600160a01b039091166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff90911617825550612f25565b6004841415612e6e576000612dcb83850185613ec0565b61ffff8089166000908152600b602090815260408083209385168352929052205490915060ff1680612dff575061ffff8116155b612e1b5760405162461bcd60e51b81526004016108f290614589565b815461ffff9091167e01000000000000000000000000000000000000000000000000000000000000027dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116178155612f25565b6005841415612ec6576000612e85838501856142ad565b6001830180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff9290921691909117905550612f25565b6006841415611631576000612edd83850185613c1e565b6001830180546001600160a01b0390921668010000000000000000027fffffffff0000000000000000000000000000000000000000ffffffffffffffff909216919091179055505b83856001600160a01b03167ffc01bf86212a14151d51d1be5c2ac64d67d5ec823dfc6f53298d7ce3f3d3d2528585604051612f6192919061450d565b60405180910390a3505050505050565b600082821115612fc8576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b612fd6613ad1565b6001600160a01b03808316600090815260066020908152604080832061ffff808916808652918452828520835160c0810185528154808416825267ffffffffffffffff6201000082048116838901526a010000000000000000000082048a16838801527e010000000000000000000000000000000000000000000000000000000000009091048416606083015260019092015491821660808201526801000000000000000090910490961660a0870152908452600790925290912082519091166130a357805461ffff1682525b602082015167ffffffffffffffff166130ce57805462010000900467ffffffffffffffff1660208301525b60408201516001600160a01b03166130ff5780546a010000000000000000000090046001600160a01b031660408301525b606082015161ffff1661313a5780547e01000000000000000000000000000000000000000000000000000000000000900461ffff1660608301525b608082015167ffffffffffffffff1661316257600181015467ffffffffffffffff1660808301525b60a08201516001600160a01b031661164957600101546801000000000000000090046001600160a01b031660a08201529392505050565b60008282018381101561164b576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008151600014156132ce5761ffff808716600090815260086020908152604080832060608a015190941683529281529082902080548351601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600186161502019093169290920491820184900484028101840190945280845290918301828280156132c65780601f1061329b576101008083540402835291602001916132c6565b820191906000526020600020905b8154815290600101906020018083116132a957829003601f168201915b505050505091505b604080860151606087015191517f5886ea65000000000000000000000000000000000000000000000000000000008152909182916001600160a01b03831691635886ea6591613327918c918b908b908b906004016150a5565b602060405180830381600087803b15801561334157600080fd5b505af1158015613355573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133799190614295565b92506133858284613680565b7fb0c632f55f1e1b3b2c3d82f41ee4716bb4c00f0f5d84cdafc141581bb8757a4f8488606001516040516133ba929190614534565b60405180910390a1505095945050505050565b60a0820151606083015160808401516040517fc5e193cd000000000000000000000000000000000000000000000000000000008152600093926001600160a01b0384169263c5e193cd92613429928a92909189906004016150e1565b602060405180830381600087803b15801561344357600080fd5b505af1158015613457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061347b9190614295565b91506116498183613680565b6000806001600160a01b03831615806134a957506002546001600160a01b0316155b6003546040517f5cbbbd750000000000000000000000000000000000000000000000000000000081529192506000916001600160a01b0390911690635cbbbd75906134fd908515908b908b906004016144ab565b60206040518083038186803b15801561351557600080fd5b505afa158015613529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061354d9190614295565b905080156135e757811561357a576003546001600160a01b03166135718183613680565b819350506135e7565b846001600160a01b0316846001600160a01b031614806135a257506001600160a01b03841632145b6135be5760405162461bcd60e51b81526004016108f290614893565b6002546135d6906001600160a01b03168530846136c3565b6005546135e39082613199565b6005555b5050949350505050565b3390565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052613675908490613751565b505050565b3b151590565b6001600160a01b0382166000908152600460205260409020546136a39082613199565b6001600160a01b0390921660009081526004602052604090209190915550565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905261374b908590613751565b50505050565b60006137a6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166138029092919063ffffffff16565b805190915015613675578080602001905160208110156137c557600080fd5b50516136755760405162461bcd60e51b815260040180806020018281038252602a815260200180615260602a913960400191505060405180910390fd5b60606127018484600085856138168561367a565b613867576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b602083106138c357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613886565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613925576040519150601f19603f3d011682016040523d82523d6000602084013e61392a565b606091505b509150915061393a828286613945565b979650505050505050565b6060831561395457508161164b565b8251156139645782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156139ae578181015183820152602001613996565b50505050905090810190601f1680156139db5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b828054600181600116156101000203166002900490600052602060002090601f016020900481019282613a1f5760008555613a83565b82601f10613a56578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555613a83565b82800160010185558215613a83579182015b82811115613a83578235825591602001919060010190613a68565b50613a8f929150613b06565b5090565b6040805160e08101825260008082526020820181905291810182905260608082018390526080820181905260a082019290925260c081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b5b80821115613a8f5760008155600101613b07565b80356117b0816151fb565b80516117b0816151fb565b60008083601f840112613b42578182fd5b50813567ffffffffffffffff811115613b59578182fd5b602083019150836020828501011115613b7157600080fd5b9250929050565b600082601f830112613b88578081fd5b815167ffffffffffffffff811115613b9c57fe5b613bcd60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601615183565b818152846020838601011115613be1578283fd5b6127018260208301602087016151cf565b80356117b081615213565b80516117b081615213565b80356117b081615223565b80516117b081615223565b600060208284031215613c2f578081fd5b813561164b816151fb565b60008060408385031215613c4c578081fd5b8235613c57816151fb565b946020939093013593505050565b60008060408385031215613c77578182fd5b8235613c82816151fb565b91506020830135613c9281615213565b809150509250929050565b60008060008060808587031215613cb2578182fd5b8435613cbd816151fb565b93506020850135613ccd81615213565b93969395505050506040820135916060013590565b60008060408385031215613c4c578182fd5b60008060008060008060008060008060006101008c8e031215613d15578687fd5b613d1e8c613b1b565b9a50613d2c60208d01613c08565b9950613d3a60408d01613bf2565b985067ffffffffffffffff8060608e01351115613d55578788fd5b613d658e60608f01358f01613b31565b909950975060808d0135811015613d7a578687fd5b613d8a8e60808f01358f01613b31565b9097509550613d9b60a08e01613b1b565b9450613da960c08e01613b1b565b93508060e08e01351115613dbb578283fd5b50613dcc8d60e08e01358e01613b31565b81935080925050509295989b509295989b9093969950565b600060208284031215613df5578081fd5b815167ffffffffffffffff80821115613e0c578283fd5b9083019060e08286031215613e1f578283fd5b613e2960e0615183565b613e3283613bfd565b8152613e4060208401613bfd565b6020820152613e5160408401613c13565b6040820152613e6260608401613b26565b6060820152608083015182811115613e78578485fd5b613e8487828601613b78565b60808301525060a083015160a082015260c083015182811115613ea5578485fd5b613eb187828601613b78565b60c08301525095945050505050565b600060208284031215613ed1578081fd5b813561164b81615213565b60008060408385031215613eee578182fd5b8235613ef981615213565b91506020830135613c92816151fb565b600080600080600080600060a0888a031215613f23578081fd5b8735613f2e81615213565b96506020880135613f3e816151fb565b9550604088013567ffffffffffffffff80821115613f5a578283fd5b613f668b838c01613b31565b909750955060608a013591508115158214613f7f578283fd5b90935060808901359080821115613f94578283fd5b50613fa18a828b01613b31565b989b979a50959850939692959293505050565b600080600060608486031215613fc8578081fd5b8335613fd381615213565b92506020840135613fe3816151fb565b929592945050506040919091013590565b600080600080600080600060c0888a03121561400e578081fd5b873561401981615213565b96506020880135614029816151fb565b955060408801359450606088013593506080880135925060a088013567ffffffffffffffff811115614059578182fd5b613fa18a828b01613b31565b60008060008060006080868803121561407c578283fd5b853561408781615213565b94506020860135614097816151fb565b935060408601359250606086013567ffffffffffffffff8111156140b9578182fd5b6140c588828901613b31565b969995985093965092949392505050565b600080604083850312156140e8578182fd5b8235613c5781615213565b60008060008060808587031215614108578182fd5b843561411381615213565b966020860135965060408601359560600135945092505050565b600080600060408486031215614141578081fd5b833561414c81615213565b9250602084013567ffffffffffffffff811115614167578182fd5b61417386828701613b31565b9497909650939450505050565b60008060408385031215614192578182fd5b8235613c8281615213565b600080600080606085870312156141b2578182fd5b84356141bd81615213565b935060208501356141cd81615213565b9250604085013567ffffffffffffffff8111156141e8578283fd5b6141f487828801613b31565b95989497509550505050565b600080600080600080600060e0888a03121561421a578081fd5b873561422581615213565b9650602088013561423581615213565b9550604088013561424581615223565b94506060880135614255816151fb565b9350608088013561426581615213565b925060a088013561427581615223565b915060c0880135614285816151fb565b8091505092959891949750929550565b6000602082840312156142a6578081fd5b5051919050565b6000602082840312156142be578081fd5b813561164b81615223565b6000602082840312156142da578081fd5b815161164b81615223565b600082845282826020860137806020848601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011685010190509392505050565b600081518084526143458160208601602086016151cf565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600083516143898184602088016151cf565b60609390931b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190920190815260140192915050565b90565b60007fffffffffffffffff0000000000000000000000000000000000000000000000008860c01b1682527fffff000000000000000000000000000000000000000000000000000000000000808860f01b1660088401527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008760601b16600a840152808660f01b16601e8401525083516144648160208501602088016151cf565b8083019050835161447c8160208401602088016151cf565b0160200198975050505050505050565b6001600160a01b0391909116815260200190565b901515815260200190565b92151583526020830191909152604082015260600190565b90815260200190565b9283526020830191909152604082015260600190565b6000858252606060208301526144fc6060830185876142e5565b905082604083015295945050505050565b6000602082526127016020830184866142e5565b60006020825261164b602083018461432d565b600060408252614547604083018561432d565b905061ffff831660208301529392505050565b60006060825261456d606083018661432d565b67ffffffffffffffff9490941660208301525060400152919050565b60208082526026908201527f4c617965725a65726f3a20696e76616c6964206f7574626f756e642070726f6f60408201527f6620747970650000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f4c617965725a65726f3a20647374436861696e496420646f6573206e6f74206560408201527f7869737400000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526018908201527f4c617965725a65726f3a206f6e6c792074726561737572790000000000000000604082015260600190565b6020808252601e908201527f4c617965725a65726f3a20496e76616c696420636f6e66696720747970650000604082015260600190565b6020808252601a908201527f4c617965725a65726f3a207769746864726177206661696c6564000000000000604082015260600190565b60208082526025908201527f4c617965725a65726f3a206e6f7420656e6f756768206e617469766520666f7260408201527f2066656573000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526025908201527f4c617965725a65726f3a205f746f2063616e6e6f74206265207a65726f20616460408201527f6472657373000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526031908201527f4c617965725a65726f3a205f6c617965725a65726f546f6b656e2063616e6e6f60408201527f74206265207a65726f2061646472657373000000000000000000000000000000606082015260800190565b60208082526022908201527f4c617965725a65726f3a20696e76616c69642072656c6179657220616464726560408201527f7373000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601b908201527f4c617965725a65726f3a206661696c656420746f20726566756e640000000000604082015260600190565b6020808252602b908201527f4c617965725a65726f3a206d75737420626520706169642062792073656e646560408201527f72206f72206f726967696e000000000000000000000000000000000000000000606082015260800190565b6020808252601d908201527f4c617965725a65726f3a20696e76616c69642064737441646472657373000000604082015260600190565b60208082526021908201527f4c617965725a65726f3a20696e76616c6964206f7261636c652061646472657360408201527f7300000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526025908201527f4c617965725a65726f3a20696e76616c6964205f7061636b65742e756c6e416460408201527f6472657373000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601e908201527f4c617965725a65726f3a20696e76616c696420737263436861696e2049640000604082015260600190565b6020808252601a908201527f4c617965725a65726f3a20696e76616c69642072656c61796572000000000000604082015260600190565b6020808252601a908201527f4c617965725a65726f3a2077726f6e6720706174682064617461000000000000604082015260600190565b60208082526029908201527f4c617965725a65726f3a206c6962726172792063616e6e6f74206265207a657260408201527f6f20616464726573730000000000000000000000000000000000000000000000606082015260800190565b60208082526043908201527f4c617965725a65726f3a206f7261636c6520646174612063616e206f6e6c792060408201527f75706461746520696620697420686173206d6f726520636f6e6669726d61746960608201527f6f6e730000000000000000000000000000000000000000000000000000000000608082015260a00190565b6020808252601e908201527f4c617965725a65726f3a20696e76616c696420647374436861696e2049640000604082015260600190565b60208082526030908201527f4c617965725a65726f3a20696e76616c696420696e626f756e642070726f6f6660408201527f206c6962726172792076657273696f6e00000000000000000000000000000000606082015260800190565b60208082526022908201527f4c617965725a65726f3a20696e76616c6964207372634164647265737320736960408201527f7a65000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602a908201527f4c617965725a65726f3a2074726561737572792063616e6e6f74206265207a6560408201527f726f206164647265737300000000000000000000000000000000000000000000606082015260800190565b60208082526021908201527f4c617965725a65726f3a2072656d6f746520756c6e20616c726561647920736560408201527f7400000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526022908201527f4c617965725a65726f3a2063616e206e6f7420616464206e6577206c6962726160408201527f7279000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526018908201527f4c617965725a65726f3a206f6e6c7920656e64706f696e740000000000000000604082015260600190565b6020808252602e908201527f4c617965725a65726f3a20696e76616c6964206f7574626f756e6420626c6f6360408201527f6b20636f6e6669726d6174696f6e000000000000000000000000000000000000606082015260800190565b60208082526028908201527f4c617965725a65726f3a20696e636f72726563742072656d6f7465206164647260408201527f6573732073697a65000000000000000000000000000000000000000000000000606082015260800190565b60208082526030908201527f4c617965725a65726f3a2072656d6f746520636861696e20616464726573732060408201527f73697a6520616c72656164792073657400000000000000000000000000000000606082015260800190565b6020808252602d908201527f4c617965725a65726f3a20696e76616c696420696e626f756e6420626c6f636b60408201527f20636f6e6669726d6174696f6e00000000000000000000000000000000000000606082015260800190565b60208082526029908201527f4c617965725a65726f3a206e6f7420656e6f75676820626c6f636b20636f6e6660408201527f69726d6174696f6e730000000000000000000000000000000000000000000000606082015260800190565b600060c08201905061ffff808451168352602084015167ffffffffffffffff8082166020860152604086015191506001600160a01b0380831660408701528360608801511660608701528160808801511660808701528060a08801511660a08701525050505092915050565b61ffff91909116815260200190565b600061ffff851682526001600160a01b03841660208301526060604083015261501d606083018461432d565b95945050505050565b600061ffff851682526040602083015261501d6040830184866142e5565b600061ffff8816825260c0602083015261506160c083018861432d565b6001600160a01b038716604084015267ffffffffffffffff8616606084015284608084015282810360a0840152615098818561432d565b9998505050505050505050565b600061ffff80881683528087166020840152506001600160a01b038516604083015283606083015260a0608083015261393a60a083018461432d565b61ffff948516815292909316602083015267ffffffffffffffff1660408201526001600160a01b03909116606082015260800190565b61ffff968716815267ffffffffffffffff95861660208201526001600160a01b03948516604082015292909516606083015290921660808301529190911660a082015260c00190565b918252602082015260400190565b67ffffffffffffffff91909116815260200190565b60405181810167ffffffffffffffff8111828210171561519f57fe5b604052919050565b600080858511156151b6578182fd5b838611156151c2578182fd5b5050820193919092039150565b60005b838110156151ea5781810151838201526020016151d2565b8381111561374b5750506000910152565b6001600160a01b038116811461521057600080fd5b50565b61ffff8116811461521057600080fd5b67ffffffffffffffff8116811461521057600080fdfe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220dc6fc63e061b7f8d887a5dcc9daf06630498d5f3c9e5ed30999f3b436f801b0664736f6c63430007060033000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd700000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67500000000000000000000000000000000000000000000000000000000000000b8
Deployed Bytecode
0x6080604052600436106102e75760003560e01c80638317814a11610184578063d543c774116100d6578063ed28580a1161008a578063f47a5feb11610064578063f47a5feb146107f6578063f58589a21461080b578063f8e1734c1461082b576102e7565b8063ed28580a14610796578063f0f44260146107b6578063f2fde38b146107d6576102e7565b8063ddfdef5a116100bb578063ddfdef5a14610736578063ea216c2114610756578063eb0d4c3114610776576102e7565b8063d543c774146106e9578063db00719b14610716576102e7565b8063959f594311610138578063b77d22ad11610112578063b77d22ad14610687578063b8e7e3e01461069c578063b9a99bed146106bc576102e7565b8063959f59431461061a578063987fa2d51461063a578063a46622221461065a576102e7565b806387078f9f1161016957806387078f9f146105d05780638da5cb5b146105f0578063904d3b8d14610605576102e7565b80638317814a146105905780638525b711146105b0576102e7565b806352d2871f1161023d5780636a14ac82116101f1578063759c5b3b116101cb578063759c5b3b1461053b5780638140666e1461055b5780638207f79d14610570576102e7565b80636a14ac82146104e6578063704316e514610506578063715018a614610526576102e7565b80635b056da5116102225780635b056da51461048f5780635e280f11146104b157806369412bfa146104c6576102e7565b806352d2871f1461044f57806352d3b5001461046f576102e7565b80632cfacb061161029f57806340a7bb101161027957806340a7bb10146103f957806349148c37146104275780634d3a0f7c1461043c576102e7565b80632cfacb06146103905780632f813464146103b257806331bd2430146103e4576102e7565b806307b9ca7c116102d057806307b9ca7c1461033957806318da00111461034e5780632a819bbf14610363576102e7565b806302bd9743146102ec57806307b18bde14610317575b600080fd5b3480156102f857600080fd5b5061030161084b565b60405161030e919061448c565b60405180910390f35b34801561032357600080fd5b50610337610332366004613c3a565b61086f565b005b34801561034557600080fd5b506103016109f9565b34801561035a57600080fd5b50610301610a08565b34801561036f57600080fd5b5061038361037e366004614180565b610a17565b60405161030e9190614521565b34801561039c57600080fd5b506103a5610ad9565b60405161030e91906144c3565b3480156103be57600080fd5b506103d26103cd366004613ec0565b610ade565b60405161030e96959493929190615117565b3480156103f057600080fd5b506103a5610b62565b34801561040557600080fd5b50610419610414366004613f09565b610b67565b60405161030e929190615160565b34801561043357600080fd5b506103a5610e97565b61033761044a366004613cf4565b610e9c565b34801561045b57600080fd5b5061038361046a366004613fb4565b6112e8565b34801561047b57600080fd5b5061033761048a366004613c1e565b611652565b34801561049b57600080fd5b506104a461174e565b60405161030e9190614fe2565b3480156104bd57600080fd5b50610301611772565b3480156104d257600080fd5b506103a56104e1366004613c1e565b611796565b3480156104f257600080fd5b50610337610501366004614200565b6117b5565b34801561051257600080fd5b506103376105213660046140f3565b611b17565b34801561053257600080fd5b50610337611bdc565b34801561054757600080fd5b506103a5610556366004613c9d565b611cb2565b34801561056757600080fd5b506103a5611cde565b34801561057c57600080fd5b5061033761058b366004613edc565b611ce3565b34801561059c57600080fd5b506103376105ab36600461419d565b611e7c565b3480156105bc57600080fd5b506103376105cb366004613ce2565b611f65565b3480156105dc57600080fd5b506103376105eb3660046140d6565b612067565b3480156105fc57600080fd5b5061030161215e565b34801561061157600080fd5b506103a561216d565b34801561062657600080fd5b506103a5610635366004613ec0565b612172565b34801561064657600080fd5b50610337610655366004613ff4565b612184565b34801561066657600080fd5b5061067a610675366004613edc565b612618565b60405161030e9190614f76565b34801561069357600080fd5b506103a561262a565b3480156106a857600080fd5b506104a46106b7366004613ec0565b61262f565b3480156106c857600080fd5b506106dc6106d736600461412d565b612645565b60405161030e919061516e565b3480156106f557600080fd5b50610709610704366004614180565b612709565b60405161030e91906144a0565b34801561072257600080fd5b50610301610731366004614180565b612729565b34801561074257600080fd5b506103d2610751366004613c65565b61274f565b34801561076257600080fd5b506103a5610771366004613ec0565b6127de565b34801561078257600080fd5b50610337610791366004614180565b6127f0565b3480156107a257600080fd5b506103376107b13660046140d6565b6128de565b3480156107c257600080fd5b506103376107d1366004613c1e565b6129c9565b3480156107e257600080fd5b506103376107f1366004613c1e565b612ac5565b34801561080257600080fd5b506103a5612bf2565b34801561081757600080fd5b506103a5610826366004613c1e565b612bf8565b34801561083757600080fd5b50610337610846366004614065565b612c0a565b7f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67581565b600260005414156108c7576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556001600160a01b0382166108fb5760405162461bcd60e51b81526004016108f290614745565b60405180910390fd5b336000908152600460205260409020546109159082612f71565b336000908152600460205260408082209290925590516001600160a01b038416908390610941906143c1565b60006040518083038185875af1925050503d806000811461097e576040519150601f19603f3d011682016040523d82523d6000602084013e610983565b606091505b50509050806109a45760405162461bcd60e51b81526004016108f2906146b1565b826001600160a01b0316336001600160a01b03167f3bfd26201736b5cb14a562ab3cfc2bef76901726e3a78483d6288af47131e1d9846040516109e791906144c3565b60405180910390a35050600160005550565b6002546001600160a01b031681565b6003546001600160a01b031681565b60086020908152600092835260408084208252918352918190208054825160026001831615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190921691909104601f810185900485028201850190935282815292909190830182828015610ad15780601f10610aa657610100808354040283529160200191610ad1565b820191906000526020600020905b815481529060010190602001808311610ab457829003601f168201915b505050505081565b600381565b6007602052600090815260409020805460019091015461ffff8083169267ffffffffffffffff6201000082048116936001600160a01b036a010000000000000000000084048116947e010000000000000000000000000000000000000000000000000000000000009094049093169291811691680100000000000000009091041686565b600681565b6000806000610b768a8a612fce565b905060608415610bbf5785858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929350610c8e92505050565b61ffff808c166000908152600860209081526040808320606087015190941683529281529082902080548351601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018616150201909316929092049182018490048402810184019094528084529091830182828015610c865780601f10610c5b57610100808354040283529160200191610c86565b820191906000526020600020905b815481529060010190602001808311610c6957829003601f168201915b505050505090505b600082604001516001600160a01b031663c03f15298d85606001518e8e8e9050876040518663ffffffff1660e01b8152600401610ccf9594939291906150a5565b60206040518083038186803b158015610ce757600080fd5b505afa158015610cfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1f9190614295565b905060008b905060008460a001516001600160a01b0316635553fb8e8f87606001518860800151866040518563ffffffff1660e01b8152600401610d6694939291906150e1565b60206040518083038186803b158015610d7e57600080fd5b505afa158015610d92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db69190614295565b6003546040517f5cbbbd750000000000000000000000000000000000000000000000000000000081529192506000916001600160a01b0390911690635cbbbd7590610e09908e90889087906004016144ab565b60206040518083038186803b158015610e2157600080fd5b505afa158015610e35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e599190614295565b90508a610e695780975087610e6e565b809650865b50610e8382610e7d8a87613199565b90613199565b975050505050505097509795505050505050565b600281565b7f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76001600160a01b03163314610ee45760405162461bcd60e51b81526004016108f290614d6e565b61ffff89166000908152600e60205260409020548b908a90610f185760405162461bcd60e51b81526004016108f2906145e6565b61ffff81166000908152600c6020526040812054606091908015801590610f415750601481018c145b610f5d5760405162461bcd60e51b81526004016108f290614e02565b6000808e8e8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505083810160140151925090506001600160a01b0387811690831614610fcc5760405162461bcd60e51b81526004016108f290614a4f565b8e8e6000908592610fdf939291906151a7565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040517f6fe7b673000000000000000000000000000000000000000000000000000000008152929750506001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6751691636fe7b673915061107f9089908b908690600401614ff1565b602060405180830381600087803b15801561109957600080fd5b505af11580156110ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d191906142c9565b935050505060008a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093945061111d9250879150889050612fce565b9050600061116586838986518d8d8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506131f392505050565b9050600061117487848a6133cd565b9050600061118483838b8f613487565b9050600061119682610e7d8686613199565b9050348111156111b85760405162461bcd60e51b81526004016108f2906146e8565b60006111c43483612f71565b9050801561124a5760008f6001600160a01b0316826040516111e5906143c1565b60006040518083038185875af1925050503d8060008114611222576040519150601f19603f3d011682016040523d82523d6000602084013e611227565b606091505b50509050806112485760405162461bcd60e51b81526004016108f29061485c565b505b6000887f00000000000000000000000000000000000000000000000000000000000000b88d8d8d8c604051602001611287969594939291906143c4565b60405160208183030381529060405290507fe9bded5f24a4168e4f3bf44e00298c993b22376aad8c58c7dda9718a54cbea82816040516112c79190614521565b60405180910390a15050505050505050505050505050505050505050505050565b6001600160a01b038216600090815260066020908152604080832061ffff871684529091529020606090600183141561137c57805461ffff166113665761ffff80861660009081526007602090815260409182902054915161134f93929092169101614fe2565b60405160208183030381529060405291505061164b565b805460405161134f9161ffff1690602001614fe2565b60028314156113f257805462010000900467ffffffffffffffff166113d05761ffff851660009081526007602090815260409182902054915161134f9262010000900467ffffffffffffffff16910161516e565b805460405161134f9162010000900467ffffffffffffffff169060200161516e565b600383141561147d5780546a010000000000000000000090046001600160a01b03166114545761ffff851660009081526007602090815260409182902054915161134f926a010000000000000000000090046001600160a01b0316910161448c565b805460405161134f916a010000000000000000000090046001600160a01b03169060200161448c565b60048314156115365780547e01000000000000000000000000000000000000000000000000000000000000900461ffff166114fe5761ffff80861660009081526007602090815260409182902054915161134f937e010000000000000000000000000000000000000000000000000000000000009093049092169101614fe2565b805460405161134f917e01000000000000000000000000000000000000000000000000000000000000900461ffff1690602001614fe2565b60058314156115a357600181015467ffffffffffffffff166115845761ffff851660009081526007602090815260409182902060010154915161134f9267ffffffffffffffff16910161516e565b600181015460405161134f9167ffffffffffffffff169060200161516e565b60068314156116315760018101546801000000000000000090046001600160a01b03166116075761ffff851660009081526007602090815260409182902060010154915161134f926801000000000000000090046001600160a01b0316910161448c565b600181015460405161134f916801000000000000000090046001600160a01b03169060200161448c565b60405162461bcd60e51b81526004016108f29061467a565b505b9392505050565b61165a6135f1565b6001600160a01b031661166b61215e565b6001600160a01b0316146116c6576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166116ec5760405162461bcd60e51b81526004016108f2906147a2565b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f33d644987381deff4408951d55afa136f124e22a7810b163b2aaa3ebef770f6490600090a250565b7f00000000000000000000000000000000000000000000000000000000000000b881565b7f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd781565b6001600160a01b0381166000908152600460205260409020545b919050565b6117bd6135f1565b6001600160a01b03166117ce61215e565b6001600160a01b031614611829576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b61ffff8088166000908152600a6020526040902054811690871611801590611855575060008661ffff16115b6118715760405162461bcd60e51b81526004016108f290614b9d565b60008567ffffffffffffffff161161189b5760405162461bcd60e51b81526004016108f290614ebc565b6001600160a01b0384166118c15760405162461bcd60e51b81526004016108f2906147ff565b61ffff8088166000908152600b602090815260408083209387168352929052205460ff166119015760405162461bcd60e51b81526004016108f290614589565b60008267ffffffffffffffff161161192b5760405162461bcd60e51b81526004016108f290614da5565b6001600160a01b0381166119515760405162461bcd60e51b81526004016108f290614927565b6040518060c001604052808761ffff1681526020018667ffffffffffffffff168152602001856001600160a01b031681526020018461ffff1681526020018367ffffffffffffffff168152602001826001600160a01b0316815250600760008961ffff1661ffff16815260200190815260200160002060008201518160000160006101000a81548161ffff021916908361ffff16021790555060208201518160000160026101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550604082015181600001600a6101000a8154816001600160a01b0302191690836001600160a01b03160217905550606082015181600001601e6101000a81548161ffff021916908361ffff16021790555060808201518160010160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a08201518160010160086101000a8154816001600160a01b0302191690836001600160a01b031602179055509050508661ffff167f5a76432853a0871c4e780def7f3ffc7912339b53f022ac31127fe5ff84a36fa1878787878787604051611b0696959493929190615117565b60405180910390a250505050505050565b336000908152600d6020908152604080832061ffff8816845282528083208684528252808320848452909152902054828110611b655760405162461bcd60e51b81526004016108f290614ae3565b336000818152600d6020908152604080832061ffff8a1680855290835281842089855283528184208785529092529182902086905590517f74bbc026808dcba59692d6a8bb20596849ca718e10e2432c6cdf48af865bc5d990611bcd908890879089906144cc565b60405180910390a35050505050565b611be46135f1565b6001600160a01b0316611bf561215e565b6001600160a01b031614611c50576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b600d60209081526000948552604080862082529385528385208152918452828420909152825290205481565b600481565b611ceb6135f1565b6001600160a01b0316611cfc61215e565b6001600160a01b031614611d57576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b038116611d7d5760405162461bcd60e51b81526004016108f290614a86565b61ffff8083166000908152600a60205260409020548116908110611db35760405162461bcd60e51b81526004016108f290614d11565b61ffff8381166000818152600a6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660019790970195861696871790556009825280832095835294905283902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03861617905591519091907f802d55279d51813cb7a9a98e8fd2d7bec5346cb830901c11b85d1650cb857e9a90611e6f90859061448c565b60405180910390a2505050565b611e846135f1565b6001600160a01b0316611e9561215e565b6001600160a01b031614611ef0576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b61ffff8085166000908152600860209081526040808320938716835292905220611f1b9083836139e9565b508261ffff168461ffff167f4a5695eee2a74d548d5f5c485a3de99ace99e3b664c8e30a90f49be6ebb549328484604051611f5792919061450d565b60405180910390a350505050565b60026000541415611fbd576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556003546001600160a01b03163314611fec5760405162461bcd60e51b81526004016108f290614643565b600554611ff99082612f71565b600555600254612013906001600160a01b031683836135f5565b816001600160a01b0316336001600160a01b03167f3a20c8c3cd1848485ae8261a52398bb9b26f195b717306b3cf7f058e62c095d58360405161205691906144c3565b60405180910390a350506001600055565b61206f6135f1565b6001600160a01b031661208061215e565b6001600160a01b0316146120db576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b61ffff82166000908152600c60205260409020541561210c5760405162461bcd60e51b81526004016108f290614e5f565b61ffff82166000818152600c602052604090819020839055517f0611bb2107e385b79ec826fff8ecc1c1248a7aae3c875c96668f8cfbf1734220906121529084906144c3565b60405180910390a25050565b6001546001600160a01b031690565b600581565b600c6020526000908152604090205481565b60006121908888612fce565b60408101519091506001600160a01b031633146121bf5760405162461bcd60e51b81526004016108f290614a18565b6121c7613a93565b61ffff89166000908152600c6020526040902054806121f85760405162461bcd60e51b81526004016108f290614e02565b60a08301516001600160a01b03166000908152600d6020908152604080832061ffff8e16845282528083208a8452825280832089845290915290205480158015906122515750836020015167ffffffffffffffff168110155b61226d5760405162461bcd60e51b81526004016108f290614f19565b61ffff808c166000908152600960209081526040808320885190941683529290528190205490517fb71e0f710000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690819063b71e0f71906122df908b908b908b9089906004016144e2565b600060405180830381600087803b1580156122f957600080fd5b505af115801561230d573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526123539190810190613de4565b60a081015161ffff8e166000908152600e6020526040902054919550149150508015612382575060a082015115155b61239e5760405162461bcd60e51b81526004016108f290614984565b8961ffff16826000015161ffff16146123c95760405162461bcd60e51b81526004016108f2906149e1565b80826080015151146123ed5760405162461bcd60e51b81526004016108f290614bfa565b7f00000000000000000000000000000000000000000000000000000000000000b861ffff16826020015161ffff16146124385760405162461bcd60e51b81526004016108f290614b66565b886001600160a01b031682606001516001600160a01b03161461246d5760405162461bcd60e51b81526004016108f2906148f0565b6124768961367a565b6124e75781606001516001600160a01b0316826000015161ffff167fa2786598bd84ae4a299103996359e6cb4333404583256079dfc279386baf5832846080015185604001518660c00151805190602001206040516124d79392919061455a565b60405180910390a350505061260f565b600082608001518360600151604051602001612504929190614377565b604051602081830303815290604052905082606001516001600160a01b0316836000015161ffff167f2bd2d8a84b748439fd50d79a49502b4eb5faa25b864da6a9ab5c150704be9a4d856080015186604001518760c00151805190602001206040516125729392919061455a565b60405180910390a37f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76001600160a01b031663c2fa48138c838d87604001518e8960c001516040518763ffffffff1660e01b81526004016125d896959493929190615044565b600060405180830381600087803b1580156125f257600080fd5b505af1158015612606573d6000803e3d6000fd5b50505050505050505b50505050505050565b612620613ad1565b61164b8383612fce565b600181565b600a6020526000908152604090205461ffff1681565b6040517fc533338f0000000000000000000000000000000000000000000000000000000081526000906001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675169063c533338f906126b190879087908790600401615026565b60206040518083038186803b1580156126c957600080fd5b505afa1580156126dd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270191906142c9565b949350505050565b600b60209081526000928352604080842090915290825290205460ff1681565b60096020908152600092835260408084209091529082529020546001600160a01b031681565b60066020908152600092835260408084209091529082529020805460019091015461ffff8083169267ffffffffffffffff6201000082048116936001600160a01b036a010000000000000000000084048116947e010000000000000000000000000000000000000000000000000000000000009094049093169291811691680100000000000000009091041686565b600e6020526000908152604090205481565b6127f86135f1565b6001600160a01b031661280961215e565b6001600160a01b031614612864576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b61ffff8083166000818152600b60209081526040808320948616835293905282902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517fec23bee6f88cfecebb09d6aaaed66f0ce110debc1f61117c8270a7116597df9a90612152908490614fe2565b6128e66135f1565b6001600160a01b03166128f761215e565b6001600160a01b031614612952576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b61ffff82166000908152600e6020526040902054156129835760405162461bcd60e51b81526004016108f290614cb4565b61ffff82166000818152600e602052604090819020839055517f0dad975e1d2fbe771c95cdcc7be9a1e61181de7173abe0a32b8f8f83140873e5906121529084906144c3565b6129d16135f1565b6001600160a01b03166129e261215e565b6001600160a01b031614612a3d576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b038116612a635760405162461bcd60e51b81526004016108f290614c57565b600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517fcb7ef3e545f5cdb893f5c568ba710fe08f336375a2d9fd66e161033f8fc09ef390600090a250565b612acd6135f1565b6001600160a01b0316612ade61215e565b6001600160a01b031614612b39576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b038116612b7e5760405162461bcd60e51b815260040180806020018281038252602681526020018061523a6026913960400191505060405180910390fd5b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b60055481565b60046020526000908152604090205481565b7f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76001600160a01b03163314612c525760405162461bcd60e51b81526004016108f290614d6e565b6001600160a01b038416600090815260066020908152604080832061ffff8916845290915290206001841415612cff576000612c9083850185613ec0565b61ffff8089166000908152600a60205260409020549192509081169082161115612ccc5760405162461bcd60e51b81526004016108f290614b9d565b81547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff91909116178155612f25565b6002841415612d56576000612d16838501856142ad565b825467ffffffffffffffff90911662010000027fffffffffffffffffffffffffffffffffffffffffffff0000000000000000ffff90911617825550612f25565b6003841415612db4576000612d6d83850185613c1e565b82546001600160a01b039091166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff90911617825550612f25565b6004841415612e6e576000612dcb83850185613ec0565b61ffff8089166000908152600b602090815260408083209385168352929052205490915060ff1680612dff575061ffff8116155b612e1b5760405162461bcd60e51b81526004016108f290614589565b815461ffff9091167e01000000000000000000000000000000000000000000000000000000000000027dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116178155612f25565b6005841415612ec6576000612e85838501856142ad565b6001830180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff9290921691909117905550612f25565b6006841415611631576000612edd83850185613c1e565b6001830180546001600160a01b0390921668010000000000000000027fffffffff0000000000000000000000000000000000000000ffffffffffffffff909216919091179055505b83856001600160a01b03167ffc01bf86212a14151d51d1be5c2ac64d67d5ec823dfc6f53298d7ce3f3d3d2528585604051612f6192919061450d565b60405180910390a3505050505050565b600082821115612fc8576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b612fd6613ad1565b6001600160a01b03808316600090815260066020908152604080832061ffff808916808652918452828520835160c0810185528154808416825267ffffffffffffffff6201000082048116838901526a010000000000000000000082048a16838801527e010000000000000000000000000000000000000000000000000000000000009091048416606083015260019092015491821660808201526801000000000000000090910490961660a0870152908452600790925290912082519091166130a357805461ffff1682525b602082015167ffffffffffffffff166130ce57805462010000900467ffffffffffffffff1660208301525b60408201516001600160a01b03166130ff5780546a010000000000000000000090046001600160a01b031660408301525b606082015161ffff1661313a5780547e01000000000000000000000000000000000000000000000000000000000000900461ffff1660608301525b608082015167ffffffffffffffff1661316257600181015467ffffffffffffffff1660808301525b60a08201516001600160a01b031661164957600101546801000000000000000090046001600160a01b031660a08201529392505050565b60008282018381101561164b576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008151600014156132ce5761ffff808716600090815260086020908152604080832060608a015190941683529281529082902080548351601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600186161502019093169290920491820184900484028101840190945280845290918301828280156132c65780601f1061329b576101008083540402835291602001916132c6565b820191906000526020600020905b8154815290600101906020018083116132a957829003601f168201915b505050505091505b604080860151606087015191517f5886ea65000000000000000000000000000000000000000000000000000000008152909182916001600160a01b03831691635886ea6591613327918c918b908b908b906004016150a5565b602060405180830381600087803b15801561334157600080fd5b505af1158015613355573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133799190614295565b92506133858284613680565b7fb0c632f55f1e1b3b2c3d82f41ee4716bb4c00f0f5d84cdafc141581bb8757a4f8488606001516040516133ba929190614534565b60405180910390a1505095945050505050565b60a0820151606083015160808401516040517fc5e193cd000000000000000000000000000000000000000000000000000000008152600093926001600160a01b0384169263c5e193cd92613429928a92909189906004016150e1565b602060405180830381600087803b15801561344357600080fd5b505af1158015613457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061347b9190614295565b91506116498183613680565b6000806001600160a01b03831615806134a957506002546001600160a01b0316155b6003546040517f5cbbbd750000000000000000000000000000000000000000000000000000000081529192506000916001600160a01b0390911690635cbbbd75906134fd908515908b908b906004016144ab565b60206040518083038186803b15801561351557600080fd5b505afa158015613529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061354d9190614295565b905080156135e757811561357a576003546001600160a01b03166135718183613680565b819350506135e7565b846001600160a01b0316846001600160a01b031614806135a257506001600160a01b03841632145b6135be5760405162461bcd60e51b81526004016108f290614893565b6002546135d6906001600160a01b03168530846136c3565b6005546135e39082613199565b6005555b5050949350505050565b3390565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052613675908490613751565b505050565b3b151590565b6001600160a01b0382166000908152600460205260409020546136a39082613199565b6001600160a01b0390921660009081526004602052604090209190915550565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905261374b908590613751565b50505050565b60006137a6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166138029092919063ffffffff16565b805190915015613675578080602001905160208110156137c557600080fd5b50516136755760405162461bcd60e51b815260040180806020018281038252602a815260200180615260602a913960400191505060405180910390fd5b60606127018484600085856138168561367a565b613867576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b602083106138c357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613886565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613925576040519150601f19603f3d011682016040523d82523d6000602084013e61392a565b606091505b509150915061393a828286613945565b979650505050505050565b6060831561395457508161164b565b8251156139645782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156139ae578181015183820152602001613996565b50505050905090810190601f1680156139db5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b828054600181600116156101000203166002900490600052602060002090601f016020900481019282613a1f5760008555613a83565b82601f10613a56578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555613a83565b82800160010185558215613a83579182015b82811115613a83578235825591602001919060010190613a68565b50613a8f929150613b06565b5090565b6040805160e08101825260008082526020820181905291810182905260608082018390526080820181905260a082019290925260c081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b5b80821115613a8f5760008155600101613b07565b80356117b0816151fb565b80516117b0816151fb565b60008083601f840112613b42578182fd5b50813567ffffffffffffffff811115613b59578182fd5b602083019150836020828501011115613b7157600080fd5b9250929050565b600082601f830112613b88578081fd5b815167ffffffffffffffff811115613b9c57fe5b613bcd60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601615183565b818152846020838601011115613be1578283fd5b6127018260208301602087016151cf565b80356117b081615213565b80516117b081615213565b80356117b081615223565b80516117b081615223565b600060208284031215613c2f578081fd5b813561164b816151fb565b60008060408385031215613c4c578081fd5b8235613c57816151fb565b946020939093013593505050565b60008060408385031215613c77578182fd5b8235613c82816151fb565b91506020830135613c9281615213565b809150509250929050565b60008060008060808587031215613cb2578182fd5b8435613cbd816151fb565b93506020850135613ccd81615213565b93969395505050506040820135916060013590565b60008060408385031215613c4c578182fd5b60008060008060008060008060008060006101008c8e031215613d15578687fd5b613d1e8c613b1b565b9a50613d2c60208d01613c08565b9950613d3a60408d01613bf2565b985067ffffffffffffffff8060608e01351115613d55578788fd5b613d658e60608f01358f01613b31565b909950975060808d0135811015613d7a578687fd5b613d8a8e60808f01358f01613b31565b9097509550613d9b60a08e01613b1b565b9450613da960c08e01613b1b565b93508060e08e01351115613dbb578283fd5b50613dcc8d60e08e01358e01613b31565b81935080925050509295989b509295989b9093969950565b600060208284031215613df5578081fd5b815167ffffffffffffffff80821115613e0c578283fd5b9083019060e08286031215613e1f578283fd5b613e2960e0615183565b613e3283613bfd565b8152613e4060208401613bfd565b6020820152613e5160408401613c13565b6040820152613e6260608401613b26565b6060820152608083015182811115613e78578485fd5b613e8487828601613b78565b60808301525060a083015160a082015260c083015182811115613ea5578485fd5b613eb187828601613b78565b60c08301525095945050505050565b600060208284031215613ed1578081fd5b813561164b81615213565b60008060408385031215613eee578182fd5b8235613ef981615213565b91506020830135613c92816151fb565b600080600080600080600060a0888a031215613f23578081fd5b8735613f2e81615213565b96506020880135613f3e816151fb565b9550604088013567ffffffffffffffff80821115613f5a578283fd5b613f668b838c01613b31565b909750955060608a013591508115158214613f7f578283fd5b90935060808901359080821115613f94578283fd5b50613fa18a828b01613b31565b989b979a50959850939692959293505050565b600080600060608486031215613fc8578081fd5b8335613fd381615213565b92506020840135613fe3816151fb565b929592945050506040919091013590565b600080600080600080600060c0888a03121561400e578081fd5b873561401981615213565b96506020880135614029816151fb565b955060408801359450606088013593506080880135925060a088013567ffffffffffffffff811115614059578182fd5b613fa18a828b01613b31565b60008060008060006080868803121561407c578283fd5b853561408781615213565b94506020860135614097816151fb565b935060408601359250606086013567ffffffffffffffff8111156140b9578182fd5b6140c588828901613b31565b969995985093965092949392505050565b600080604083850312156140e8578182fd5b8235613c5781615213565b60008060008060808587031215614108578182fd5b843561411381615213565b966020860135965060408601359560600135945092505050565b600080600060408486031215614141578081fd5b833561414c81615213565b9250602084013567ffffffffffffffff811115614167578182fd5b61417386828701613b31565b9497909650939450505050565b60008060408385031215614192578182fd5b8235613c8281615213565b600080600080606085870312156141b2578182fd5b84356141bd81615213565b935060208501356141cd81615213565b9250604085013567ffffffffffffffff8111156141e8578283fd5b6141f487828801613b31565b95989497509550505050565b600080600080600080600060e0888a03121561421a578081fd5b873561422581615213565b9650602088013561423581615213565b9550604088013561424581615223565b94506060880135614255816151fb565b9350608088013561426581615213565b925060a088013561427581615223565b915060c0880135614285816151fb565b8091505092959891949750929550565b6000602082840312156142a6578081fd5b5051919050565b6000602082840312156142be578081fd5b813561164b81615223565b6000602082840312156142da578081fd5b815161164b81615223565b600082845282826020860137806020848601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011685010190509392505050565b600081518084526143458160208601602086016151cf565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600083516143898184602088016151cf565b60609390931b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190920190815260140192915050565b90565b60007fffffffffffffffff0000000000000000000000000000000000000000000000008860c01b1682527fffff000000000000000000000000000000000000000000000000000000000000808860f01b1660088401527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008760601b16600a840152808660f01b16601e8401525083516144648160208501602088016151cf565b8083019050835161447c8160208401602088016151cf565b0160200198975050505050505050565b6001600160a01b0391909116815260200190565b901515815260200190565b92151583526020830191909152604082015260600190565b90815260200190565b9283526020830191909152604082015260600190565b6000858252606060208301526144fc6060830185876142e5565b905082604083015295945050505050565b6000602082526127016020830184866142e5565b60006020825261164b602083018461432d565b600060408252614547604083018561432d565b905061ffff831660208301529392505050565b60006060825261456d606083018661432d565b67ffffffffffffffff9490941660208301525060400152919050565b60208082526026908201527f4c617965725a65726f3a20696e76616c6964206f7574626f756e642070726f6f60408201527f6620747970650000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f4c617965725a65726f3a20647374436861696e496420646f6573206e6f74206560408201527f7869737400000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526018908201527f4c617965725a65726f3a206f6e6c792074726561737572790000000000000000604082015260600190565b6020808252601e908201527f4c617965725a65726f3a20496e76616c696420636f6e66696720747970650000604082015260600190565b6020808252601a908201527f4c617965725a65726f3a207769746864726177206661696c6564000000000000604082015260600190565b60208082526025908201527f4c617965725a65726f3a206e6f7420656e6f756768206e617469766520666f7260408201527f2066656573000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526025908201527f4c617965725a65726f3a205f746f2063616e6e6f74206265207a65726f20616460408201527f6472657373000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526031908201527f4c617965725a65726f3a205f6c617965725a65726f546f6b656e2063616e6e6f60408201527f74206265207a65726f2061646472657373000000000000000000000000000000606082015260800190565b60208082526022908201527f4c617965725a65726f3a20696e76616c69642072656c6179657220616464726560408201527f7373000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601b908201527f4c617965725a65726f3a206661696c656420746f20726566756e640000000000604082015260600190565b6020808252602b908201527f4c617965725a65726f3a206d75737420626520706169642062792073656e646560408201527f72206f72206f726967696e000000000000000000000000000000000000000000606082015260800190565b6020808252601d908201527f4c617965725a65726f3a20696e76616c69642064737441646472657373000000604082015260600190565b60208082526021908201527f4c617965725a65726f3a20696e76616c6964206f7261636c652061646472657360408201527f7300000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526025908201527f4c617965725a65726f3a20696e76616c6964205f7061636b65742e756c6e416460408201527f6472657373000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601e908201527f4c617965725a65726f3a20696e76616c696420737263436861696e2049640000604082015260600190565b6020808252601a908201527f4c617965725a65726f3a20696e76616c69642072656c61796572000000000000604082015260600190565b6020808252601a908201527f4c617965725a65726f3a2077726f6e6720706174682064617461000000000000604082015260600190565b60208082526029908201527f4c617965725a65726f3a206c6962726172792063616e6e6f74206265207a657260408201527f6f20616464726573730000000000000000000000000000000000000000000000606082015260800190565b60208082526043908201527f4c617965725a65726f3a206f7261636c6520646174612063616e206f6e6c792060408201527f75706461746520696620697420686173206d6f726520636f6e6669726d61746960608201527f6f6e730000000000000000000000000000000000000000000000000000000000608082015260a00190565b6020808252601e908201527f4c617965725a65726f3a20696e76616c696420647374436861696e2049640000604082015260600190565b60208082526030908201527f4c617965725a65726f3a20696e76616c696420696e626f756e642070726f6f6660408201527f206c6962726172792076657273696f6e00000000000000000000000000000000606082015260800190565b60208082526022908201527f4c617965725a65726f3a20696e76616c6964207372634164647265737320736960408201527f7a65000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602a908201527f4c617965725a65726f3a2074726561737572792063616e6e6f74206265207a6560408201527f726f206164647265737300000000000000000000000000000000000000000000606082015260800190565b60208082526021908201527f4c617965725a65726f3a2072656d6f746520756c6e20616c726561647920736560408201527f7400000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526022908201527f4c617965725a65726f3a2063616e206e6f7420616464206e6577206c6962726160408201527f7279000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526018908201527f4c617965725a65726f3a206f6e6c7920656e64706f696e740000000000000000604082015260600190565b6020808252602e908201527f4c617965725a65726f3a20696e76616c6964206f7574626f756e6420626c6f6360408201527f6b20636f6e6669726d6174696f6e000000000000000000000000000000000000606082015260800190565b60208082526028908201527f4c617965725a65726f3a20696e636f72726563742072656d6f7465206164647260408201527f6573732073697a65000000000000000000000000000000000000000000000000606082015260800190565b60208082526030908201527f4c617965725a65726f3a2072656d6f746520636861696e20616464726573732060408201527f73697a6520616c72656164792073657400000000000000000000000000000000606082015260800190565b6020808252602d908201527f4c617965725a65726f3a20696e76616c696420696e626f756e6420626c6f636b60408201527f20636f6e6669726d6174696f6e00000000000000000000000000000000000000606082015260800190565b60208082526029908201527f4c617965725a65726f3a206e6f7420656e6f75676820626c6f636b20636f6e6660408201527f69726d6174696f6e730000000000000000000000000000000000000000000000606082015260800190565b600060c08201905061ffff808451168352602084015167ffffffffffffffff8082166020860152604086015191506001600160a01b0380831660408701528360608801511660608701528160808801511660808701528060a08801511660a08701525050505092915050565b61ffff91909116815260200190565b600061ffff851682526001600160a01b03841660208301526060604083015261501d606083018461432d565b95945050505050565b600061ffff851682526040602083015261501d6040830184866142e5565b600061ffff8816825260c0602083015261506160c083018861432d565b6001600160a01b038716604084015267ffffffffffffffff8616606084015284608084015282810360a0840152615098818561432d565b9998505050505050505050565b600061ffff80881683528087166020840152506001600160a01b038516604083015283606083015260a0608083015261393a60a083018461432d565b61ffff948516815292909316602083015267ffffffffffffffff1660408201526001600160a01b03909116606082015260800190565b61ffff968716815267ffffffffffffffff95861660208201526001600160a01b03948516604082015292909516606083015290921660808301529190911660a082015260c00190565b918252602082015260400190565b67ffffffffffffffff91909116815260200190565b60405181810167ffffffffffffffff8111828210171561519f57fe5b604052919050565b600080858511156151b6578182fd5b838611156151c2578182fd5b5050820193919092039150565b60005b838110156151ea5781810151838201526020016151d2565b8381111561374b5750506000910152565b6001600160a01b038116811461521057600080fd5b50565b61ffff8116811461521057600080fd5b67ffffffffffffffff8116811461521057600080fdfe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220dc6fc63e061b7f8d887a5dcc9daf06630498d5f3c9e5ed30999f3b436f801b0664736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd700000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67500000000000000000000000000000000000000000000000000000000000000b8
-----Decoded View---------------
Arg [0] : _endpoint (address): 0xb6319cC6c8c27A8F5dAF0dD3DF91EA35C4720dd7
Arg [1] : _nonceContract (address): 0x66A71Dcef29A0fFBDBE3c6a460a3B5BC225Cd675
Arg [2] : _localChainId (uint16): 184
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd7
Arg [1] : 00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000b8
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.