ERC-721
Overview
Max Total Supply
10,000 ZKX
Holders
5,032
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
0 ZKXLoading...
Loading
Loading...
Loading
Loading...
Loading
Contract Name:
ONFT721Psi
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 1 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./ONFT721Core.sol"; import "../ERC721Psi/ERC721Psi.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; contract ONFT721Psi is ONFT721Core, ERC721Psi { using Strings for uint256; struct RoyaltyInfo { address recipient; uint24 amount; } string public collectionURI; string public tokensURI; RoyaltyInfo private _royalties; constructor( string memory _name, string memory _symbol, string memory _collectionURI, string memory _tokensURI, address _owner, uint256 _minGasToTransfer, address _lzEndpoint ) ERC721Psi(_name, _symbol) ONFT721Core(_minGasToTransfer, _lzEndpoint) { collectionURI = _collectionURI; tokensURI = _tokensURI; owner = _owner; _setNextTokenId(0); } function premint(uint256 _quantity) external onlyOwner { require(totalSupply() <= 10000); _safeMint(owner, _quantity); } function _baseURI() internal pure returns (string memory) { return "ipfs://"; } function contractURI() public view returns (string memory) { return string(abi.encodePacked(_baseURI(), collectionURI)); } function tokenURI(uint256 tokenId) public view returns (string memory) { return string(abi.encodePacked(_baseURI(), tokensURI, "/", tokenId.toString(), ".json")); } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Psi, ONFT721Core) returns (bool) { return super.supportsInterface(interfaceId); } function _debitFrom(address _from, uint16, bytes memory, uint _tokenId) internal virtual override { require(_isApprovedOrOwner(msg.sender, _tokenId), "send caller is not owner nor approved"); require(ERC721Psi.ownerOf(_tokenId) == _from, "send from incorrect owner"); _transfer(_from, address(this), _tokenId); } function _creditTo(uint16, address _toAddress, uint _tokenId) internal virtual override { require(!_exists(_tokenId) || (_exists(_tokenId) && ERC721Psi.ownerOf(_tokenId) == address(this))); if (!_exists(_tokenId)) { _safeMint(_toAddress, _tokenId); } else { _transfer(address(this), _toAddress, _tokenId); } } function setTrustedRemoteAndLimits( uint16 _remoteChainId, bytes calldata _remoteAddress, uint256 _dstChainIdToTransferGas, uint256 _dstChainIdToBatchLimit ) external onlyOwner { require(_dstChainIdToTransferGas > 0, "dstChainIdToTransferGas must be > 0"); dstChainIdToTransferGas[_remoteChainId] = _dstChainIdToTransferGas; require(_dstChainIdToBatchLimit > 0, "dstChainIdToBatchLimit must be > 0"); dstChainIdToBatchLimit[_remoteChainId] = _dstChainIdToBatchLimit; trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this)); emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress); } function royaltyInfo(uint256, uint256 value) external view returns (address receiver, uint256 royaltyAmount) { RoyaltyInfo memory royalties = _royalties; receiver = royalties.recipient; royaltyAmount = (value * royalties.amount) / 10000; } function setRoyaltyAmount(uint24 _amount) external onlyOwner { _royalties.amount = _amount; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IONFT721Core.sol"; import "../lzApp/NonblockingLzApp.sol"; import "../interfaces/IONFTReceiver.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; abstract contract ONFT721Core is NonblockingLzApp, ERC165, IONFT721Core { uint16 public constant FUNCTION_TYPE_SEND = 1; uint private constant BP_DENOMINATOR = 10000; uint16 public feeBp; address private _manager; struct StoredCredit { uint16 srcChainId; address toAddress; uint256 index; bool creditsRemain; } uint256 public minGasToTransferAndStore; // min amount of gas required to transfer, and also store the payload mapping(uint16 => uint256) public dstChainIdToBatchLimit; mapping(uint16 => uint256) public dstChainIdToTransferGas; // per transfer amount of gas required to mint/transfer on the dst mapping(bytes32 => StoredCredit) public storedCredits; constructor(uint256 _minGasToTransferAndStore, address _lzEndpoint) NonblockingLzApp(_lzEndpoint) { require(_minGasToTransferAndStore > 0); minGasToTransferAndStore = _minGasToTransferAndStore; _manager = address(0x61104fBe07ecc735D8d84422c7f045f8d29DBf15); feeBp = 1000; } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IONFT721Core).interfaceId || super.supportsInterface(interfaceId); } function estimateSendFee(uint16 _dstChainId, bytes memory _toAddress, uint _tokenId, bool _useZro, bytes memory _adapterParams) public view virtual override returns (uint nativeFee, uint zroFee) { return estimateSendBatchFee(_dstChainId, _toAddress, _toSingletonArray(_tokenId), _useZro, _adapterParams, bytes('')); } function estimateSendBatchFee(uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, bool _useZro, bytes memory _adapterParams, bytes memory _payloadForCall) public view virtual override returns (uint nativeFee, uint zroFee) { bytes memory payload = abi.encode(_toAddress, _toAddress, _tokenIds, _payloadForCall); (nativeFee, zroFee) = lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams); uint fee = nativeFee * feeBp / BP_DENOMINATOR; nativeFee += fee; } function sendFrom(address _from, uint16 _dstChainId, bytes memory _toAddress, uint _tokenId, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) public payable virtual override { _send(_from, _dstChainId, _toAddress, _toSingletonArray(_tokenId), _refundAddress, _zroPaymentAddress, _adapterParams, bytes(''), bytes('')); } function sendBatchFrom(address _from, uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams, bytes memory _receiver, bytes memory _payloadForCall) public payable virtual override { _send(_from, _dstChainId, _toAddress, _tokenIds, _refundAddress, _zroPaymentAddress, _adapterParams, _receiver, _payloadForCall); } function _send(address _from, uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams, bytes memory _receiver, bytes memory _payloadForCall) internal virtual { require(_tokenIds.length > 0, "tokenIds[] is empty"); require(_tokenIds.length <= dstChainIdToBatchLimit[_dstChainId], "batch size exceeds dst batch limit"); for (uint i = 0; i < _tokenIds.length; i++) { _debitFrom(_from, _dstChainId, _toAddress, _tokenIds[i]); } bytes memory payload = abi.encode(_toAddress, _receiver, _tokenIds, _payloadForCall); _checkGasLimit(_dstChainId, FUNCTION_TYPE_SEND, _adapterParams, dstChainIdToTransferGas[_dstChainId] * _tokenIds.length); (uint nativeFee) = _payONFTFee(msg.value); _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams, nativeFee); emit SendToChain(_dstChainId, _from, _toAddress, _tokenIds); } function _nonblockingLzReceive( uint16 _srcChainId, bytes memory _srcAddress, uint64, /*_nonce*/ bytes memory _payload ) internal virtual override { (bytes memory toAddressBytes, bytes memory receiverBytes, uint[] memory tokenIds, bytes memory payloadForCall) = abi.decode(_payload, (bytes, bytes, uint[], bytes)); address toAddress; address receiver; assembly { toAddress := mload(add(toAddressBytes, 20)) receiver := mload(add(receiverBytes, 40)) } uint nextIndex = _creditTill(_srcChainId, toAddress, 0, tokenIds); if (nextIndex < tokenIds.length) { // not enough gas to complete transfers, store to be cleared in another tx bytes32 hashedPayload = keccak256(_payload); storedCredits[hashedPayload] = StoredCredit(_srcChainId, toAddress, nextIndex, true); emit CreditStored(hashedPayload, _payload); } emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, tokenIds); if (nextIndex == tokenIds.length && receiver != address(0)) { // workaround for stack too deep uint16 srcChainId = _srcChainId; bytes memory srcAddress = _srcAddress; address toAddress_ = toAddress; address receiver_ = receiver; uint[] memory tokenIds_ = tokenIds; bytes memory payloadForCall_ = payloadForCall; IONFTReceiver(receiver_).onONFTReceived(srcChainId, srcAddress, toAddress_, tokenIds_, payloadForCall_); } } // Public function for anyone to clear and deliver the remaining batch sent tokenIds function clearCredits(bytes memory _payload) external { bytes32 hashedPayload = keccak256(_payload); require(storedCredits[hashedPayload].creditsRemain); (,,uint[] memory tokenIds,) = abi.decode(_payload, (bytes, bytes, uint[], bytes)); uint nextIndex = _creditTill(storedCredits[hashedPayload].srcChainId, storedCredits[hashedPayload].toAddress, storedCredits[hashedPayload].index, tokenIds); require(nextIndex > storedCredits[hashedPayload].index); if (nextIndex == tokenIds.length) { // cleared the credits, delete the element delete storedCredits[hashedPayload]; emit CreditCleared(hashedPayload); } else { // store the next index to mint storedCredits[hashedPayload] = StoredCredit(storedCredits[hashedPayload].srcChainId, storedCredits[hashedPayload].toAddress, nextIndex, true); } } // When a srcChain has the ability to transfer more chainIds in a single tx than the dst can do. // Needs the ability to iterate and stop if the minGasToTransferAndStore is not met function _creditTill(uint16 _srcChainId, address _toAddress, uint _startIndex, uint[] memory _tokenIds) internal returns (uint256){ uint i = _startIndex; while (i < _tokenIds.length) { // if not enough gas to process, store this index for next loop if (gasleft() < minGasToTransferAndStore) break; _creditTo(_srcChainId, _toAddress, _tokenIds[i]); i++; } // indicates the next index to send of tokenIds, // if i == tokenIds.length, we are finished return i; } function setMinGasToTransferAndStore(uint256 _minGasToTransferAndStore) external onlyOwner { require(_minGasToTransferAndStore > 0); minGasToTransferAndStore = _minGasToTransferAndStore; } // ensures enough gas in adapter params to handle batch transfer gas amounts on the dst function setDstChainIdToTransferGas(uint16 _dstChainId, uint256 _dstChainIdToTransferGas) external onlyOwner { require(_dstChainIdToTransferGas > 0); dstChainIdToTransferGas[_dstChainId] = _dstChainIdToTransferGas; } // limit on src the amount of tokens to batch send function setDstChainIdToBatchLimit(uint16 _dstChainId, uint256 _dstChainIdToBatchLimit) external onlyOwner { require(_dstChainIdToBatchLimit > 0); dstChainIdToBatchLimit[_dstChainId] = _dstChainIdToBatchLimit; } function setManager(address _newManager) external { require(msg.sender == _manager); _manager = _newManager; } function setFeeBp(uint16 _feeBp) public virtual { require(msg.sender == _manager); require(_feeBp <= BP_DENOMINATOR); feeBp = _feeBp; } function _payONFTFee(uint _nativeFee) internal virtual returns (uint amount) { uint fee = _nativeFee * feeBp / BP_DENOMINATOR; amount = _nativeFee - fee; if (fee > 0) { (bool p,) = payable(_manager).call{value : (fee)}(""); require(p, "!fee"); } } function transferOwnership(address _owner) external onlyOwner { owner = _owner; } function _debitFrom(address _from, uint16 _dstChainId, bytes memory _toAddress, uint _tokenId) internal virtual; function _creditTo(uint16 _srcChainId, address _toAddress, uint _tokenId) internal virtual; function _toSingletonArray(uint element) internal pure returns (uint[] memory) { uint[] memory array = new uint[](1); array[0] = element; return array; } }
// SPDX-License-Identifier: MIT /** ______ _____ _____ ______ ___ __ _ _ _ | ____| __ \ / ____|____ |__ \/_ | || || | | |__ | |__) | | / / ) || | \| |/ | | __| | _ /| | / / / / | |\_ _/ | |____| | \ \| |____ / / / /_ | | | | |______|_| \_\\_____|/_/ |____||_| |_| - github: https://github.com/estarriolvetch/ERC721Psi - npm: https://www.npmjs.com/package/erc721psi */ pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import "./solidity-bits/BitMaps.sol"; contract ERC721Psi is ERC165, IERC721 { using Strings for uint256; using BitMaps for BitMaps.BitMap; BitMaps.BitMap private _batchHead; string private _name; string private _symbol; mapping(uint256 => address) internal _owners; uint256 private _currentIndex; mapping(uint256 => address) private _tokenApprovals; mapping(address => mapping(address => bool)) private _operatorApprovals; uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } function _startTokenId() internal view virtual returns (uint256) { return 0; } function _setNextTokenId(uint256 _index) internal virtual { require(_currentIndex == 0); _currentIndex = _index; } function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } function totalMinted() public view virtual returns (uint256) { return _currentIndex - _startTokenId(); } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || super.supportsInterface(interfaceId); } function balanceOf(address owner) public view virtual override returns (uint) { require(owner != address(0), "ERC721Psi: balance query for the zero address"); uint count; for( uint i = _startTokenId(); i < _nextTokenId(); ++i ){ if(_exists(i)){ if( owner == ownerOf(i)){ ++count; } } } return count; } function ownerOf(uint256 tokenId) public view virtual override returns (address) { (address owner, ) = _ownerAndBatchHeadOf(tokenId); return owner; } function _ownerAndBatchHeadOf(uint256 tokenId) internal view returns (address owner, uint256 tokenIdBatchHead){ require(_exists(tokenId), "ERC721Psi: owner query for nonexistent token"); tokenIdBatchHead = _getBatchHead(tokenId); owner = _owners[tokenIdBatchHead]; } function name() public view virtual returns (string memory) { return _name; } function symbol() public view virtual returns (string memory) { return _symbol; } function approve(address to, uint256 tokenId) public virtual override { address owner = ownerOf(tokenId); require(to != owner, "ERC721Psi: approval to current owner"); require( msg.sender == owner || isApprovedForAll(owner, msg.sender), "ERC721Psi: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } function getApproved(uint256 tokenId) public view virtual override returns (address) { require( _exists(tokenId), "ERC721Psi: approved query for nonexistent token" ); return _tokenApprovals[tokenId]; } function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != msg.sender, "ERC721Psi: approve to caller"); _operatorApprovals[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } function transferFrom( address from, address to, uint256 tokenId ) public virtual override { require( _isApprovedOrOwner(msg.sender, tokenId), "ERC721Psi: transfer caller is not owner nor approved" ); _transfer(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { require( _isApprovedOrOwner(msg.sender, tokenId), "ERC721Psi: transfer caller is not owner nor approved" ); _safeTransfer(from, to, tokenId, _data); } function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); require( _checkOnERC721Received(from, to, tokenId, 1,_data), "ERC721Psi: transfer to non ERC721Receiver implementer" ); } function _exists(uint256 tokenId) internal view virtual returns (bool) { return tokenId < _nextTokenId() && _startTokenId() <= tokenId; } function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require( _exists(tokenId), "ERC721Psi: operator query for nonexistent token" ); address owner = ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ""); } function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { uint256 nextTokenId = _nextTokenId(); _mint(to, quantity); require( _checkOnERC721Received(address(0), to, nextTokenId, quantity, _data), "ERC721Psi: transfer to non ERC721Receiver implementer" ); } function _mint( address to, uint256 quantity ) internal virtual { uint256 nextTokenId = _nextTokenId(); require(quantity > 0, "ERC721Psi: quantity must be greater 0"); require(to != address(0), "ERC721Psi: mint to the zero address"); _beforeTokenTransfers(address(0), to, nextTokenId, quantity); _currentIndex += quantity; _owners[nextTokenId] = to; _batchHead.set(nextTokenId); uint256 toMasked; uint256 end = nextTokenId + quantity; assembly { toMasked := and(to, _BITMASK_ADDRESS) log4( 0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, nextTokenId ) for { let tokenId := add(nextTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } _afterTokenTransfers(address(0), to, nextTokenId, quantity); } function _transfer( address from, address to, uint256 tokenId ) internal virtual { (address owner, uint256 tokenIdBatchHead) = _ownerAndBatchHeadOf(tokenId); require( owner == from, "ERC721Psi: transfer of token that is not own" ); require(to != address(0), "ERC721Psi: transfer to the zero address"); _beforeTokenTransfers(from, to, tokenId, 1); _approve(address(0), tokenId); uint256 subsequentTokenId = tokenId + 1; if(!_batchHead.get(subsequentTokenId) && subsequentTokenId < _nextTokenId() ) { _owners[subsequentTokenId] = from; _batchHead.set(subsequentTokenId); } _owners[tokenId] = to; if(tokenId != tokenIdBatchHead) { _batchHead.set(tokenId); } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ownerOf(tokenId), to, tokenId); } function _checkOnERC721Received( address from, address to, uint256 startTokenId, uint256 quantity, bytes memory _data ) private returns (bool r) { if (isContract(to)) { r = true; for(uint256 tokenId = startTokenId; tokenId < startTokenId + quantity; tokenId++){ try IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data) returns (bytes4 retval) { r = r && retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721Psi: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } return r; } else { return true; } } function _getBatchHead(uint256 tokenId) internal view returns (uint256 tokenIdBatchHead) { tokenIdBatchHead = _batchHead.scanForward(tokenId); } function isContract(address account) internal view returns (bool) { return account.code.length > 0; } function totalSupply() public virtual view returns (uint256) { return totalMinted(); } function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; function toString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /** * @dev Interface of the ONFT Core standard */ interface IONFT721Core is IERC165 { /** * @dev Emitted when `_tokenIds[]` are moved from the `_sender` to (`_dstChainId`, `_toAddress`) * `_nonce` is the outbound nonce from */ event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes indexed _toAddress, uint[] _tokenIds); event ReceiveFromChain(uint16 indexed _srcChainId, bytes indexed _srcAddress, address indexed _toAddress, uint[] _tokenIds); /** * @dev Emitted when `_payload` was received from lz, but not enough gas to deliver all tokenIds */ event CreditStored(bytes32 _hashedPayload, bytes _payload); /** * @dev Emitted when `_hashedPayload` has been completely delivered */ event CreditCleared(bytes32 _hashedPayload); event CallONFTReceivedSuccess(uint16 indexed _srcChainId, bytes _srcAddress, address indexed _receiver); /** * @dev send token `_tokenId` to (`_dstChainId`, `_toAddress`) from `_from` * `_toAddress` can be any size depending on the `dstChainId`. * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token) * `_adapterParams` is a flexible bytes array to indicate messaging adapter services */ function sendFrom(address _from, uint16 _dstChainId, bytes calldata _toAddress, uint _tokenId, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable; /** * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`) * _dstChainId - L0 defined chain id to send tokens too * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain * _tokenId - token Id to transfer * _useZro - indicates to use zro to pay L0 fees * _adapterParams - flexible bytes array to indicate messaging adapter services in L0 */ function estimateSendFee(uint16 _dstChainId, bytes calldata _toAddress, uint _tokenId, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee); /** * @dev send tokens `_tokenIds[]` to (`_dstChainId`, `_toAddress`) from `_from` * `_toAddress` can be any size depending on the `dstChainId`. * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token) * `_adapterParams` is a flexible bytes array to indicate messaging adapter services * `_receiver` is optional and allows to call a composable function of the "receiver" contract * `_payloadForCall` is optional and is passed to the "receiver" contract as an additional payload */ function sendBatchFrom(address _from, uint16 _dstChainId, bytes calldata _toAddress, uint[] calldata _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams, bytes calldata _receiver, bytes memory _payloadForCall) external payable; /** * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`) * _dstChainId - L0 defined chain id to send tokens too * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain * _tokenIds[] - token Ids to transfer * _useZro - indicates to use zro to pay L0 fees * _adapterParams - flexible bytes array to indicate messaging adapter services in L0 */ function estimateSendBatchFee(uint16 _dstChainId, bytes calldata _toAddress, uint[] calldata _tokenIds, bool _useZro, bytes calldata _adapterParams, bytes memory _payloadForCall) external view returns (uint nativeFee, uint zroFee); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./LzApp.sol"; import "../util/ExcessivelySafeCall.sol"; abstract contract NonblockingLzApp is LzApp { using ExcessivelySafeCall for address; constructor(address _endpoint) LzApp(_endpoint) {} mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages; event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason); event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash); function _blockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual override { (bool success, bytes memory reason) = address(this).excessivelySafeCall(gasleft(), 150, abi.encodeWithSelector(this.nonblockingLzReceive.selector, _srcChainId, _srcAddress, _nonce, _payload)); if (!success) { _storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason); } } function _storeFailedMessage(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload, bytes memory _reason) internal virtual { failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload); emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason); } function nonblockingLzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public virtual { require(msg.sender == address(this), "NonblockingLzApp: caller must be LzApp"); _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } function _nonblockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual; function retryMessage(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public payable virtual { bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce]; require(payloadHash != bytes32(0), "NonblockingLzApp: no stored message"); require(keccak256(_payload) == payloadHash, "NonblockingLzApp: invalid payload"); failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0); _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload); emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; interface IONFTReceiver { /** * @dev Called by the ONFT contract when tokens are received from source chain. * @param _srcChainId The chain id of the source chain. * @param _srcAddress The address of the ONFT token contract on the source chain. * @param _from The address of the account that received the tokens. * @param _tokenIds The IDs of tokens. * @param _payload Additional data with no specified format. */ function onONFTReceived(uint16 _srcChainId, bytes calldata _srcAddress, address _from, uint[] memory _tokenIds, bytes calldata _payload) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../interfaces/ILayerZeroReceiver.sol"; import "../interfaces/ILayerZeroUserApplicationConfig.sol"; import "../interfaces/ILayerZeroEndpoint.sol"; import "../util/BytesLib.sol"; abstract contract LzApp is ILayerZeroReceiver, ILayerZeroUserApplicationConfig { uint constant public DEFAULT_PAYLOAD_SIZE_LIMIT = 10000; ILayerZeroEndpoint public immutable lzEndpoint; mapping(uint16 => bytes) public trustedRemoteLookup; mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup; address public owner; event SetTrustedRemote(uint16 _remoteChainId, bytes _path); event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress); event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas); modifier onlyOwner { require(msg.sender == owner, "LzApp: caller is not the owner"); _; } constructor(address _endpoint) { lzEndpoint = ILayerZeroEndpoint(_endpoint); owner = msg.sender; } function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public virtual override { require(msg.sender == address(lzEndpoint), "LzApp: invalid endpoint caller"); bytes memory trustedRemote = trustedRemoteLookup[_srcChainId]; require(_srcAddress.length == trustedRemote.length && trustedRemote.length > 0 && keccak256(_srcAddress) == keccak256(trustedRemote), "LzApp: invalid source sending contract"); _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } function _blockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual; function _lzSend(uint16 _dstChainId, bytes memory _payload, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams, uint _nativeFee) internal virtual { bytes memory trustedRemote = trustedRemoteLookup[_dstChainId]; require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source"); lzEndpoint.send{value: _nativeFee}(_dstChainId, trustedRemote, _payload, _refundAddress, _zroPaymentAddress, _adapterParams); } function _checkGasLimit(uint16 _dstChainId, uint16 _type, bytes memory _adapterParams, uint _extraGas) internal view virtual { uint providedGasLimit = _getGasLimit(_adapterParams); uint minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas; require(minGasLimit > 0, "LzApp: minGasLimit not set"); require(providedGasLimit >= minGasLimit, "LzApp: gas limit is too low"); } function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint gasLimit) { require(_adapterParams.length >= 34, "LzApp: invalid adapterParams"); assembly { gasLimit := mload(add(_adapterParams, 34)) } } function getConfig(uint16 _version, uint16 _chainId, address, uint _configType) external view returns (bytes memory) { return lzEndpoint.getConfig(_version, _chainId, address(this), _configType); } function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external override onlyOwner { lzEndpoint.setConfig(_version, _chainId, _configType, _config); } function setSendVersion(uint16 _version) external override onlyOwner { lzEndpoint.setSendVersion(_version); } function setReceiveVersion(uint16 _version) external override onlyOwner { lzEndpoint.setReceiveVersion(_version); } function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner { lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress); } function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external onlyOwner { trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this)); emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress); } function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint _minGas) external onlyOwner { require(_minGas > 0); minDstGasLookup[_dstChainId][_packetType] = _minGas; emit SetMinDstGas(_dstChainId, _packetType, _minGas); } function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) { bytes memory trustedSource = trustedRemoteLookup[_srcChainId]; return keccak256(trustedSource) == keccak256(_srcAddress); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.7.6; library ExcessivelySafeCall { uint256 constant LOW_28_MASK = 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff; function excessivelySafeCall( address _target, uint256 _gas, uint16 _maxCopy, bytes memory _calldata ) internal returns (bool, bytes memory) { // set up for assembly call uint256 _toCopy; bool _success; bytes memory _returnData = new bytes(_maxCopy); // dispatch message to recipient // by assembly calling "handle" function // we call via assembly to avoid memcopying a very large returndata // returned by a malicious contract assembly { _success := call( _gas, // gas _target, // recipient 0, // ether value add(_calldata, 0x20), // inloc mload(_calldata), // inlen 0, // outloc 0 // outlen ) // limit our copy to 256 bytes _toCopy := returndatasize() if gt(_toCopy, _maxCopy) { _toCopy := _maxCopy } // Store the length of the copied bytes mstore(_returnData, _toCopy) // copy the bytes from returndata[0:_toCopy] returndatacopy(add(_returnData, 0x20), 0, _toCopy) } return (_success, _returnData); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroReceiver { function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external; function setSendVersion(uint16 _version) external; function setReceiveVersion(uint16 _version) external; function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { function send(uint16 _dstChainId, bytes calldata _destination, bytes calldata _payload, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable; function receivePayload(uint16 _srcChainId, bytes calldata _srcAddress, address _dstAddress, uint64 _nonce, uint _gasLimit, bytes calldata _payload) external; function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64); function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64); function estimateFees(uint16 _dstChainId, address _userApplication, bytes calldata _payload, bool _payInZRO, bytes calldata _adapterParam) external view returns (uint nativeFee, uint zroFee); function getChainId() external view returns (uint16); function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external; function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool); function getSendLibraryAddress(address _userApplication) external view returns (address); function getReceiveLibraryAddress(address _userApplication) external view returns (address); function isSendingPayload() external view returns (bool); function isReceivingPayload() external view returns (bool); function getConfig(uint16 _version, uint16 _chainId, address _userApplication, uint _configType) external view returns (bytes memory); function getSendVersion(address _userApplication) external view returns (uint16); function getReceiveVersion(address _userApplication) external view returns (uint16); }
// SPDX-License-Identifier: Unlicense /* * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. */ pragma solidity >=0.8.0 <0.9.0; library BytesLib { function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory) { require(_length + 31 >= _length, "slice_overflow"); require(_bytes.length >= _start + _length, "slice_outOfBounds"); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { require(_bytes.length >= _start + 1 , "toUint8_outOfBounds"); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) { require(_bytes.length >= _start + 2, "toUint16_outOfBounds"); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) { require(_bytes.length >= _start + 4, "toUint32_outOfBounds"); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) { require(_bytes.length >= _start + 8, "toUint64_outOfBounds"); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) { require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) { require(_bytes.length >= _start + 32, "toBytes32_outOfBounds"); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT /** _____ ___ ___ __ ____ _ __ / ___/____ / (_)___/ (_) /___ __ / __ )(_) /______ \__ \/ __ \/ / / __ / / __/ / / / / __ / / __/ ___/ ___/ / /_/ / / / /_/ / / /_/ /_/ / / /_/ / / /_(__ ) /____/\____/_/_/\__,_/_/\__/\__, / /_____/_/\__/____/ /____/ - npm: https://www.npmjs.com/package/solidity-bits - github: https://github.com/estarriolvetch/solidity-bits */ pragma solidity ^0.8.0; import "./BitScan.sol"; library BitMaps { using BitScan for uint256; uint256 private constant MASK_INDEX_ZERO = (1 << 255); uint256 private constant MASK_FULL = type(uint256).max; struct BitMap { mapping(uint256 => uint256) _data; } function get(BitMap storage bitmap, uint256 index) internal view returns (bool) { uint256 bucket = index >> 8; uint256 mask = MASK_INDEX_ZERO >> (index & 0xff); return bitmap._data[bucket] & mask != 0; } function set(BitMap storage bitmap, uint256 index) internal { uint256 bucket = index >> 8; uint256 mask = MASK_INDEX_ZERO >> (index & 0xff); bitmap._data[bucket] |= mask; } function scanForward(BitMap storage bitmap, uint256 index) internal view returns (uint256 setBitIndex) { uint256 bucket = index >> 8; // index within the bucket uint256 bucketIndex = (index & 0xff); // load a bitboard from the bitmap. uint256 bb = bitmap._data[bucket]; // offset the bitboard to scan from `bucketIndex`. bb = bb >> (0xff ^ bucketIndex); // bb >> (255 - bucketIndex) if(bb > 0) { unchecked { setBitIndex = (bucket << 8) | (bucketIndex - bb.bitScanForward256()); } } else { while(true) { require(bucket > 0, "BitMaps: The set bit before the index doesn't exist."); unchecked { bucket--; } // No offset. Always scan from the least significiant bit now. bb = bitmap._data[bucket]; if(bb > 0) { unchecked { setBitIndex = (bucket << 8) | (255 - bb.bitScanForward256()); break; } } } } } }
// SPDX-License-Identifier: MIT /** _____ ___ ___ __ ____ _ __ / ___/____ / (_)___/ (_) /___ __ / __ )(_) /______ \__ \/ __ \/ / / __ / / __/ / / / / __ / / __/ ___/ ___/ / /_/ / / / /_/ / / /_/ /_/ / / /_/ / / /_(__ ) /____/\____/_/_/\__,_/_/\__/\__, / /_____/_/\__/____/ /____/ - npm: https://www.npmjs.com/package/solidity-bits - github: https://github.com/estarriolvetch/solidity-bits */ pragma solidity ^0.8.0; library BitScan { uint256 constant private DEBRUIJN_256 = 0x818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff; bytes constant private LOOKUP_TABLE_256 = hex"0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8"; /** @dev Isolate the least significant set bit. */ function isolateLS1B256(uint256 bb) pure internal returns (uint256) { require(bb > 0); unchecked { return bb & (0 - bb); } } /** @dev Isolate the most significant set bit. */ function isolateMS1B256(uint256 bb) pure internal returns (uint256) { require(bb > 0); unchecked { bb |= bb >> 128; bb |= bb >> 64; bb |= bb >> 32; bb |= bb >> 16; bb |= bb >> 8; bb |= bb >> 4; bb |= bb >> 2; bb |= bb >> 1; return (bb >> 1) + 1; } } /** @dev Find the index of the lest significant set bit. (trailing zero count) */ function bitScanForward256(uint256 bb) pure internal returns (uint8) { unchecked { return uint8(LOOKUP_TABLE_256[(isolateLS1B256(bb) * DEBRUIJN_256) >> 248]); } } /** @dev Find the index of the most significant set bit. */ function bitScanReverse256(uint256 bb) pure internal returns (uint8) { unchecked { return 255 - uint8(LOOKUP_TABLE_256[((isolateMS1B256(bb) * DEBRUIJN_256) >> 248)]); } } function log2(uint256 bb) pure internal returns (uint8) { unchecked { return uint8(LOOKUP_TABLE_256[(isolateMS1B256(bb) * DEBRUIJN_256) >> 248]); } } }
{ "optimizer": { "enabled": true, "runs": 1 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"_collectionURI","type":"string"},{"internalType":"string","name":"_tokensURI","type":"string"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_minGasToTransfer","type":"uint256"},{"internalType":"address","name":"_lzEndpoint","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","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":"_receiver","type":"address"}],"name":"CallONFTReceivedSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_hashedPayload","type":"bytes32"}],"name":"CreditCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_hashedPayload","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"CreditStored","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"_reason","type":"bytes"}],"name":"MessageFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":true,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":true,"internalType":"address","name":"_toAddress","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"ReceiveFromChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"_payloadHash","type":"bytes32"}],"name":"RetryMessageSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"bytes","name":"_toAddress","type":"bytes"},{"indexed":false,"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"SendToChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"_type","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_minDstGas","type":"uint256"}],"name":"SetMinDstGas","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_path","type":"bytes"}],"name":"SetTrustedRemote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"SetTrustedRemoteAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DEFAULT_PAYLOAD_SIZE_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FUNCTION_TYPE_SEND","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"clearCredits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectionURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"dstChainIdToBatchLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"dstChainIdToTransferGas","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"},{"internalType":"bytes","name":"_payloadForCall","type":"bytes"}],"name":"estimateSendBatchFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"failedMessages","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeBp","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"forceResumeReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"_configType","type":"uint256"}],"name":"getConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"isTrustedRemote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lzEndpoint","outputs":[{"internalType":"contract ILayerZeroEndpoint","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"minDstGasLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minGasToTransferAndStore","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"nonblockingLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"premint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"retryMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"},{"internalType":"bytes","name":"_receiver","type":"bytes"},{"internalType":"bytes","name":"_payloadForCall","type":"bytes"}],"name":"sendBatchFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"sendFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"_configType","type":"uint256"},{"internalType":"bytes","name":"_config","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstChainIdToBatchLimit","type":"uint256"}],"name":"setDstChainIdToBatchLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstChainIdToTransferGas","type":"uint256"}],"name":"setDstChainIdToTransferGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_feeBp","type":"uint16"}],"name":"setFeeBp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newManager","type":"address"}],"name":"setManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint16","name":"_packetType","type":"uint16"},{"internalType":"uint256","name":"_minGas","type":"uint256"}],"name":"setMinDstGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minGasToTransferAndStore","type":"uint256"}],"name":"setMinGasToTransferAndStore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setReceiveVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"_amount","type":"uint24"}],"name":"setRoyaltyAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setSendVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"setTrustedRemoteAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"bytes","name":"_remoteAddress","type":"bytes"},{"internalType":"uint256","name":"_dstChainIdToTransferGas","type":"uint256"},{"internalType":"uint256","name":"_dstChainIdToBatchLimit","type":"uint256"}],"name":"setTrustedRemoteAndLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"storedCredits","outputs":[{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"address","name":"toAddress","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bool","name":"creditsRemain","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"trustedRemoteLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b506040516200508a3803806200508a8339810160408190526200003491620002bf565b6001600160a01b038116608052600280546001600160a01b0319163317905586868383816200006257600080fd5b50600555600480546001600160b01b0319167561104fbe07ecc735d8d84422c7f045f8d29dbf1503e81790558151620000a390600a9060208501906200012f565b508051620000b990600b9060208401906200012f565b50508551620000d1915060109060208801906200012f565b508351620000e79060119060208701906200012f565b50600280546001600160a01b0319166001600160a01b0385161790556200010f60006200011c565b50505050505050620003e4565b600d54156200012a57600080fd5b600d55565b8280546200013d90620003a7565b90600052602060002090601f016020900481019282620001615760008555620001ac565b82601f106200017c57805160ff1916838001178555620001ac565b82800160010185558215620001ac579182015b82811115620001ac5782518255916020019190600101906200018f565b50620001ba929150620001be565b5090565b5b80821115620001ba5760008155600101620001bf565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001fd57600080fd5b81516001600160401b03808211156200021a576200021a620001d5565b604051601f8301601f19908116603f01168101908282118183101715620002455762000245620001d5565b816040528381526020925086838588010111156200026257600080fd5b600091505b8382101562000286578582018301518183018401529082019062000267565b83821115620002985760008385830101525b9695505050505050565b80516001600160a01b0381168114620002ba57600080fd5b919050565b600080600080600080600060e0888a031215620002db57600080fd5b87516001600160401b0380821115620002f357600080fd5b620003018b838c01620001eb565b985060208a01519150808211156200031857600080fd5b620003268b838c01620001eb565b975060408a01519150808211156200033d57600080fd5b6200034b8b838c01620001eb565b965060608a01519150808211156200036257600080fd5b50620003718a828b01620001eb565b9450506200038260808901620002a2565b925060a088015191506200039960c08901620002a2565b905092959891949750929550565b600181811c90821680620003bc57607f821691505b60208210811415620003de57634e487b7160e01b600052602260045260246000fd5b50919050565b608051614c52620004386000396000818161087501528181610a5b01528181610d6701528181610fef015281816111c2015281816113b801528181611cfd0152818161218801526131cd0152614c526000f3fe60806040526004361061027a5760003560e01c80621d35671461027f57806301ffc9a7146102a157806306fdde03146102d657806307e0db17146102f8578063081812fc14610318578063095ea7b3146103505780630b4cad4c1461037057806310ddb1371461039057806318160ddd146103b057806322a3ecf9146103d357806323b872dd146104565780632a205e3d146104765780632a55205a146104ab5780632dd0066e146104ea5780633b5aeddb146104ff5780633d8b38f61461051f57806342842e0e1461053f57806342d65a8d1461055f57806346a438161461057f578063482881901461059f5780634ac3f4ff146105b557806351905636146105e257806352a284a2146105f55780635b8c41e6146106155780636352211e1461066457806366ad5c8a1461068457806370a08231146106a45780637533d788146106c45780638cfd8f5c146106e45780638da5cb5b1461071c5780638ffa1f2a1461073c57806395d89b411461075c5780639d5aef30146107715780639ea5d6b114610791578063a22cb465146107b1578063a2309ff8146107d1578063a5097ebf146107e6578063a6c3d165146107fb578063a7e0d43d1461081b578063af3fb21c1461083b578063b353aaa714610863578063b88d4fde14610897578063c145c54b146108b7578063c4461834146108ca578063c4ed6f58146108e0578063c87b56dd146108fb578063cbed8b9c1461091b578063d0ebdbe71461093b578063d12473a51461095b578063d1deba1f1461097b578063df2a5b3b1461098e578063e8a3d485146109ae578063e985e9c5146109c3578063f2fde38b146109e3578063f5ecbdbc14610a03578063fa25f9b614610a23575b600080fd5b34801561028b57600080fd5b5061029f61029a366004613876565b610a50565b005b3480156102ad57600080fd5b506102c16102bc36600461391f565b610c81565b60405190151581526020015b60405180910390f35b3480156102e257600080fd5b506102eb610c92565b6040516102cd919061399b565b34801561030457600080fd5b5061029f6103133660046139ae565b610d24565b34801561032457600080fd5b506103386103333660046139c9565b610dcf565b6040516001600160a01b0390911681526020016102cd565b34801561035c57600080fd5b5061029f61036b366004613a02565b610e5a565b34801561037c57600080fd5b5061029f61038b3660046139c9565b610f70565b34801561039c57600080fd5b5061029f6103ab3660046139ae565b610fac565b3480156103bc57600080fd5b506103c5611026565b6040519081526020016102cd565b3480156103df57600080fd5b506104276103ee3660046139c9565b60086020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b03909316602085015291830152151560608201526080016102cd565b34801561046257600080fd5b5061029f610471366004613a2e565b611035565b34801561048257600080fd5b50610496610491366004613b42565b611066565b604080519283526020830191909152016102cd565b3480156104b757600080fd5b506104cb6104c6366004613bd0565b61109c565b604080516001600160a01b0390931683526020830191909152016102cd565b3480156104f657600080fd5b506102eb6110f1565b34801561050b57600080fd5b5061049661051a366004613c7b565b61117f565b34801561052b57600080fd5b506102c161053a366004613d47565b611290565b34801561054b57600080fd5b5061029f61055a366004613a2e565b61135c565b34801561056b57600080fd5b5061029f61057a366004613d47565b611377565b34801561058b57600080fd5b5061029f61059a366004613d99565b61141f565b3480156105ab57600080fd5b506103c560055481565b3480156105c157600080fd5b506103c56105d03660046139ae565b60066020526000908152604090205481565b61029f6105f0366004613dfd565b6115a3565b34801561060157600080fd5b5061029f610610366004613eb6565b6115da565b34801561062157600080fd5b506103c5610630366004613edb565b6003602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b34801561067057600080fd5b5061033861067f3660046139c9565b611628565b34801561069057600080fd5b5061029f61069f366004613876565b61163c565b3480156106b057600080fd5b506103c56106bf366004613f38565b611718565b3480156106d057600080fd5b506102eb6106df3660046139ae565b6117e7565b3480156106f057600080fd5b506103c56106ff366004613f55565b600160209081526000928352604080842090915290825290205481565b34801561072857600080fd5b50600254610338906001600160a01b031681565b34801561074857600080fd5b5061029f610757366004613f88565b611800565b34801561076857600080fd5b506102eb6119b1565b34801561077d57600080fd5b5061029f61078c3660046139c9565b6119c0565b34801561079d57600080fd5b5061029f6107ac366004613fbc565b611a19565b3480156107bd57600080fd5b5061029f6107cc366004613fd8565b611a67565b3480156107dd57600080fd5b506103c5611b2b565b3480156107f257600080fd5b506102eb611b3b565b34801561080757600080fd5b5061029f610816366004613d47565b611b48565b34801561082757600080fd5b5061029f6108363660046139ae565b611be9565b34801561084757600080fd5b50610850600181565b60405161ffff90911681526020016102cd565b34801561086f57600080fd5b506103387f000000000000000000000000000000000000000000000000000000000000000081565b3480156108a357600080fd5b5061029f6108b2366004614004565b611c31565b61029f6108c536600461406f565b611c63565b3480156108d657600080fd5b506103c561271081565b3480156108ec57600080fd5b506004546108509061ffff1681565b34801561090757600080fd5b506102eb6109163660046139c9565b611c7f565b34801561092757600080fd5b5061029f610936366004614183565b611cbc565b34801561094757600080fd5b5061029f610956366004613f38565b611d68565b34801561096757600080fd5b5061029f610976366004613fbc565b611daf565b61029f610989366004613876565b611dfd565b34801561099a57600080fd5b5061029f6109a93660046141f1565b612013565b3480156109ba57600080fd5b506102eb6120ac565b3480156109cf57600080fd5b506102c16109de36600461422d565b6120dd565b3480156109ef57600080fd5b5061029f6109fe366004613f38565b61210b565b348015610a0f57600080fd5b506102eb610a1e366004614266565b612157565b348015610a2f57600080fd5b506103c5610a3e3660046139ae565b60076020526000908152604090205481565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610acd5760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526020819052604081208054610aeb906142b3565b80601f0160208091040260200160405190810160405280929190818152602001828054610b17906142b3565b8015610b645780601f10610b3957610100808354040283529160200191610b64565b820191906000526020600020905b815481529060010190602001808311610b4757829003601f168201915b50505050509050805186869050148015610b7f575060008151115b8015610ba7575080516020820120604051610b9d90889088906142e8565b6040518091039020145b610c025760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610ac4565b610c788787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061221792505050565b50505050505050565b6000610c8c82612290565b92915050565b6060600a8054610ca1906142b3565b80601f0160208091040260200160405190810160405280929190818152602001828054610ccd906142b3565b8015610d1a5780601f10610cef57610100808354040283529160200191610d1a565b820191906000526020600020905b815481529060010190602001808311610cfd57829003601f168201915b5050505050905090565b6002546001600160a01b03163314610d4e5760405162461bcd60e51b8152600401610ac4906142f8565b6040516307e0db1760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906307e0db17906024015b600060405180830381600087803b158015610db457600080fd5b505af1158015610dc8573d6000803e3d6000fd5b5050505050565b6000610dda826122b5565b610e3e5760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a20617070726f76656420717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610ac4565b506000908152600e60205260409020546001600160a01b031690565b6000610e6582611628565b9050806001600160a01b0316836001600160a01b03161415610ed55760405162461bcd60e51b8152602060048201526024808201527f4552433732315073693a20617070726f76616c20746f2063757272656e74206f6044820152633bb732b960e11b6064820152608401610ac4565b336001600160a01b0382161480610ef15750610ef181336120dd565b610f615760405162461bcd60e51b815260206004820152603b60248201527f4552433732315073693a20617070726f76652063616c6c6572206973206e6f7460448201527a081bdddb995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b602a1b6064820152608401610ac4565b610f6b83836122d1565b505050565b6002546001600160a01b03163314610f9a5760405162461bcd60e51b8152600401610ac4906142f8565b60008111610fa757600080fd5b600555565b6002546001600160a01b03163314610fd65760405162461bcd60e51b8152600401610ac4906142f8565b6040516310ddb13760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906310ddb13790602401610d9a565b6000611030611b2b565b905090565b61103f338261233f565b61105b5760405162461bcd60e51b8152600401610ac49061432f565b610f6b83838361240c565b60008061108e8787611077886125e4565b87876040518060200160405280600081525061117f565b915091509550959350505050565b604080518082019091526012546001600160a01b038116808352600160a01b90910462ffffff16602083018190529091600091612710906110dd9086614399565b6110e791906143ce565b9150509250929050565b601180546110fe906142b3565b80601f016020809104026020016040519081016040528092919081815260200182805461112a906142b3565b80156111775780601f1061114c57610100808354040283529160200191611177565b820191906000526020600020905b81548152906001019060200180831161115a57829003601f168201915b505050505081565b60008060008788888660405160200161119b949392919061441d565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906340a7bb10906111ff908c90309086908c908c90600401614475565b604080518083038186803b15801561121657600080fd5b505afa15801561122a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124e91906144c9565b60045491945092506000906127109061126b9061ffff1686614399565b61127591906143ce565b905061128181856144ed565b93505050965096945050505050565b61ffff8316600090815260208190526040812080548291906112b1906142b3565b80601f01602080910402602001604051908101604052809291908181526020018280546112dd906142b3565b801561132a5780601f106112ff5761010080835404028352916020019161132a565b820191906000526020600020905b81548152906001019060200180831161130d57829003601f168201915b5050505050905083836040516113419291906142e8565b60405180910390208180519060200120149150509392505050565b610f6b83838360405180602001604052806000815250611c31565b6002546001600160a01b031633146113a15760405162461bcd60e51b8152600401610ac4906142f8565b6040516342d65a8d60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342d65a8d906113f19086908690869060040161452e565b600060405180830381600087803b15801561140b57600080fd5b505af1158015610c78573d6000803e3d6000fd5b6002546001600160a01b031633146114495760405162461bcd60e51b8152600401610ac4906142f8565b600082116114a55760405162461bcd60e51b815260206004820152602360248201527f647374436861696e4964546f5472616e73666572476173206d7573742062652060448201526203e20360ec1b6064820152608401610ac4565b61ffff85166000908152600760205260409020829055806115135760405162461bcd60e51b815260206004820152602260248201527f647374436861696e4964546f42617463684c696d6974206d757374206265203e604482015261020360f41b6064820152608401610ac4565b61ffff8516600090815260066020908152604091829020839055905161153f918691869130910161454c565b60408051601f1981840301815291815261ffff871660009081526020818152919020825161157293919290910190613767565b50600080516020614add8339815191528585856040516115949392919061452e565b60405180910390a15050505050565b610c788787876115b2886125e4565b878787604051806020016040528060008152506040518060200160405280600081525061262f565b6002546001600160a01b031633146116045760405162461bcd60e51b8152600401610ac4906142f8565b6012805462ffffff909216600160a01b0262ffffff60a01b19909216919091179055565b6000806116348361280b565b509392505050565b33301461169a5760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610ac4565b6117108686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8901819004810282018101909252878152899350915087908790819084018382808284376000920191909152506128a292505050565b505050505050565b60006001600160a01b0382166117865760405162461bcd60e51b815260206004820152602d60248201527f4552433732315073693a2062616c616e636520717565727920666f722074686560448201526c207a65726f206164647265737360981b6064820152608401610ac4565b6000805b600d548110156117e05761179d816122b5565b156117d0576117ab81611628565b6001600160a01b0316846001600160a01b031614156117d0576117cd8261456d565b91505b6117d98161456d565b905061178a565b5092915050565b600060208190529081526040902080546110fe906142b3565b80516020808301919091206000818152600890925260409091206002015460ff1661182a57600080fd5b60008280602001905181019061184091906145cd565b506000858152600860205260408120805460019091015492955090935061187f925061ffff811691620100009091046001600160a01b03169085612af2565b600084815260086020526040902060010154909150811161189f57600080fd5b81518114156119175760008381526008602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba2339061190a9085815260200190565b60405180910390a16119ab565b60408051608081018252600085815260086020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b50505050565b6060600b8054610ca1906142b3565b6002546001600160a01b031633146119ea5760405162461bcd60e51b8152600401610ac4906142f8565b6127106119f5611026565b1115611a0057600080fd5b600254611a16906001600160a01b031682612b44565b50565b6002546001600160a01b03163314611a435760405162461bcd60e51b8152600401610ac4906142f8565b60008111611a5057600080fd5b61ffff909116600090815260066020526040902055565b6001600160a01b038216331415611abf5760405162461bcd60e51b815260206004820152601c60248201527b22a9219b9918a839b49d1030b8383937bb32903a379031b0b63632b960211b6044820152606401610ac4565b336000818152600f602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600080600d5461103091906146c1565b601080546110fe906142b3565b6002546001600160a01b03163314611b725760405162461bcd60e51b8152600401610ac4906142f8565b818130604051602001611b879392919061454c565b60408051601f1981840301815291815261ffff8516600090815260208181529190208251611bba93919290910190613767565b50600080516020614add833981519152838383604051611bdc9392919061452e565b60405180910390a1505050565b6004546201000090046001600160a01b03163314611c0657600080fd5b6127108161ffff161115611c1957600080fd5b6004805461ffff191661ffff92909216919091179055565b611c3b338361233f565b611c575760405162461bcd60e51b8152600401610ac49061432f565b6119ab84848484612b62565b611c7489898989898989898961262f565b505050505050505050565b6060611c89612b97565b6011611c9484612bb8565b604051602001611ca693929190614772565b6040516020818303038152906040529050919050565b6002546001600160a01b03163314611ce65760405162461bcd60e51b8152600401610ac4906142f8565b6040516332fb62e760e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cbed8b9c90611d3a90889088908890889088906004016147cb565b600060405180830381600087803b158015611d5457600080fd5b505af1158015611c74573d6000803e3d6000fd5b6004546201000090046001600160a01b03163314611d8557600080fd5b600480546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6002546001600160a01b03163314611dd95760405162461bcd60e51b8152600401610ac4906142f8565b60008111611de657600080fd5b61ffff909116600090815260076020526040902055565b61ffff86166000908152600360205260408082209051611e2090889088906142e8565b90815260408051602092819003830190206001600160401b03871660009081529252902054905080611ea05760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610ac4565b808383604051611eb19291906142e8565b604051809103902014611f105760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610ac4565b61ffff87166000908152600360205260408082209051611f3390899089906142e8565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f88018290048202830182019052868252611fcb918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a9350915088908890819084018382808284376000920191909152506128a292505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e587878787856040516120029594939291906147f9565b60405180910390a150505050505050565b6002546001600160a01b0316331461203d5760405162461bcd60e51b8152600401610ac4906142f8565b6000811161204a57600080fd5b61ffff83811660008181526001602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611bdc565b60606120b6612b97565b60106040516020016120c9929190614834565b604051602081830303815290604052905090565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205460ff1690565b6002546001600160a01b031633146121355760405162461bcd60e51b8152600401610ac4906142f8565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5ecbdbc9060840160006040518083038186803b1580156121d257600080fd5b505afa1580156121e6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261220e9190810190614852565b95945050505050565b60008061227a5a60966366ad5c8a60e01b8989898960405160240161223f9493929190614886565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915230929190612cb5565b9150915081611710576117108686868685612d3f565b60006001600160e01b031982166380ac58cd60e01b1480610c8c5750610c8c82612dcd565b60006122c0600d5490565b82108015610c8c5750600192915050565b6000818152600e6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061230682611628565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061234a826122b5565b6123ae5760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a206f70657261746f7220717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610ac4565b60006123b983611628565b9050806001600160a01b0316846001600160a01b031614806123f45750836001600160a01b03166123e984610dcf565b6001600160a01b0316145b80612404575061240481856120dd565b949350505050565b6000806124188361280b565b91509150846001600160a01b0316826001600160a01b0316146124925760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a207472616e73666572206f6620746f6b656e2074686160448201526b3a1034b9903737ba1037bbb760a11b6064820152608401610ac4565b6001600160a01b0384166124f85760405162461bcd60e51b815260206004820152602760248201527f4552433732315073693a207472616e7366657220746f20746865207a65726f206044820152666164647265737360c81b6064820152608401610ac4565b6125036000846122d1565b60006125108460016144ed565b600881901c600090815260096020526040902054909150600160ff1b60ff83161c161580156125405750600d5481105b15612577576000818152600c6020526040902080546001600160a01b0319166001600160a01b038816179055612577600982612e02565b6000848152600c6020526040902080546001600160a01b0319166001600160a01b0387161790558184146125b0576125b0600985612e02565b83856001600160a01b0316876001600160a01b0316600080516020614afd83398151915260405160405180910390a4611710565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061261e5761261e6148c4565b602090810291909101015292915050565b60008651116126765760405162461bcd60e51b8152602060048201526013602482015272746f6b656e4964735b5d20697320656d70747960681b6044820152606401610ac4565b61ffff8816600090815260066020526040902054865111156126e55760405162461bcd60e51b815260206004820152602260248201527f62617463682073697a65206578636565647320647374206261746368206c696d6044820152611a5d60f21b6064820152608401610ac4565b60005b8651811015612728576127168a8a8a8a8581518110612709576127096148c4565b6020026020010151612e2e565b806127208161456d565b9150506126e8565b50600087838884604051602001612742949392919061441d565b6040516020818303038152906040529050612787896001868a51600760008f61ffff1661ffff168152602001908152602001600020546127829190614399565b612f02565b600061279234612fdc565b90506127a28a83898989866130ae565b886040516127b091906148da565b60405180910390208b6001600160a01b03168b61ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a8b6040516127f691906148f6565b60405180910390a45050505050505050505050565b600080612817836122b5565b6128785760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a206f776e657220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ac4565b61288183613249565b6000818152600c60205260409020546001600160a01b031694909350915050565b600080600080848060200190518101906128bc91906145cd565b6014840151602884015194985092965090945092509060006128e08b848388612af2565b905084518110156129f35760008880519060200120905060405180608001604052808d61ffff168152602001856001600160a01b03168152602001838152602001600115158152506008600083815260200190815260200160002060008201518160000160006101000a81548161ffff021916908361ffff16021790555060208201518160000160026101000a8154816001600160a01b0302191690836001600160a01b031602179055506040820151816001015560608201518160020160006101000a81548160ff0219169083151502179055509050507f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad7818a6040516129e9929190614909565b60405180910390a1505b826001600160a01b03168a604051612a0b91906148da565b60405180910390208c61ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d99026588604051612a4791906148f6565b60405180910390a4845181148015612a6757506001600160a01b03821615155b15612ae55760405163bace587f60e01b81528b908b9085908590899089906001600160a01b0384169063bace587f90612aac9089908990899088908890600401614922565b600060405180830381600087803b158015612ac657600080fd5b505af1158015612ada573d6000803e3d6000fd5b505050505050505050505b5050505050505050505050565b6000825b825181101561220e576005545a1015612b0e5761220e565b612b328686858481518110612b2557612b256148c4565b6020026020010151613256565b80612b3c8161456d565b915050612af6565b612b5e8282604051806020016040528060008152506132b6565b5050565b612b6d84848461240c565b612b7b8484846001856132d7565b6119ab5760405162461bcd60e51b8152600401610ac490614974565b604080518082019091526007815266697066733a2f2f60c81b602082015290565b606081612bdc5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612c065780612bf08161456d565b9150612bff9050600a836143ce565b9150612be0565b6000816001600160401b03811115612c2057612c20613a6f565b6040519080825280601f01601f191660200182016040528015612c4a576020820181803683370190505b5090505b841561240457612c5f6001836146c1565b9150612c6c600a866149c9565b612c779060306144ed565b60f81b818381518110612c8c57612c8c6148c4565b60200101906001600160f81b031916908160001a905350612cae600a866143ce565b9450612c4e565b6000606060008060008661ffff166001600160401b03811115612cda57612cda613a6f565b6040519080825280601f01601f191660200182016040528015612d04576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115612d26578692505b828152826000602083013e909890975095505050505050565b8180519060200120600360008761ffff1661ffff16815260200190815260200160002085604051612d7091906148da565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c9061159490879087908790879087906149dd565b60006001600160e01b031982166381af209b60e01b1480610c8c57506301ffc9a760e01b6001600160e01b0319831614610c8c565b600881901c600090815260209290925260409091208054600160ff1b60ff9093169290921c9091179055565b612e38338261233f565b612e925760405162461bcd60e51b815260206004820152602560248201527f73656e642063616c6c6572206973206e6f74206f776e6572206e6f72206170706044820152641c9bdd995960da1b6064820152608401610ac4565b836001600160a01b0316612ea582611628565b6001600160a01b031614612ef75760405162461bcd60e51b815260206004820152601960248201527839b2b73210333937b69034b731b7b93932b1ba1037bbb732b960391b6044820152606401610ac4565b6119ab84308361240c565b6000612f0d83613419565b61ffff808716600090815260016020908152604080832093891683529290529081205491925090612f3f9084906144ed565b905060008111612f8e5760405162461bcd60e51b815260206004820152601a602482015279131e905c1c0e881b5a5b91d85cd31a5b5a5d081b9bdd081cd95d60321b6044820152606401610ac4565b808210156117105760405162461bcd60e51b815260206004820152601b60248201527a4c7a4170703a20676173206c696d697420697320746f6f206c6f7760281b6044820152606401610ac4565b600454600090819061271090612ff69061ffff1685614399565b61300091906143ce565b905061300c81846146c1565b915080156130a8576004546040516000916201000090046001600160a01b03169083908381818185875af1925050503d8060008114613067576040519150601f19603f3d011682016040523d82523d6000602084013e61306c565b606091505b50509050806130a65760405162461bcd60e51b8152600401610ac4906020808252600490820152632166656560e01b604082015260600190565b505b50919050565b61ffff8616600090815260208190526040812080546130cc906142b3565b80601f01602080910402602001604051908101604052809291908181526020018280546130f8906142b3565b80156131455780601f1061311a57610100808354040283529160200191613145565b820191906000526020600020905b81548152906001019060200180831161312857829003601f168201915b505050505090508051600014156131b75760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610ac4565b60405162c5803160e81b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c580310090849061320e908b9086908c908c908c908c90600401614a1b565b6000604051808303818588803b15801561322757600080fd5b505af115801561323b573d6000803e3d6000fd5b505050505050505050505050565b6000610c8c600983613474565b61325f816122b5565b158061328b575061326f816122b5565b801561328b57503061328082611628565b6001600160a01b0316145b61329457600080fd5b61329d816122b5565b6132ab57610f6b8282612b44565b610f6b30838361240c565b60006132c1600d5490565b90506132cd848461356c565b612b7b6000858386865b60006001600160a01b0385163b1561340d57506001835b6132f884866144ed565b81101561340757604051630a85bd0160e11b81526001600160a01b0387169063150b7a02906133319033908b9086908990600401614a82565b602060405180830381600087803b15801561334b57600080fd5b505af192505050801561337b575060408051601f3d908101601f1916820190925261337891810190614abf565b60015b6133d5573d8080156133a9576040519150601f19603f3d011682016040523d82523d6000602084013e6133ae565b606091505b5080516133cd5760405162461bcd60e51b8152600401610ac490614974565b805181602001fd5b8280156133f257506001600160e01b03198116630a85bd0160e11b145b925050806133ff8161456d565b9150506132ee565b5061220e565b50600195945050505050565b600060228251101561346c5760405162461bcd60e51b815260206004820152601c60248201527b4c7a4170703a20696e76616c69642061646170746572506172616d7360201b6044820152606401610ac4565b506022015190565b600881901c60008181526020849052604081205490919060ff808516919082181c80156134b6576134a4816136e5565b60ff168203600884901b179350613563565b600083116135235760405162461bcd60e51b815260206004820152603460248201527f4269744d6170733a205468652073657420626974206265666f7265207468652060448201527334b73232bc103237b2b9b713ba1032bc34b9ba1760611b6064820152608401610ac4565b50600019909101600081815260208690526040902054909190801561355e5761354b816136e5565b60ff0360ff16600884901b179350613563565b6134b6565b50505092915050565b6000613577600d5490565b9050600082116135d75760405162461bcd60e51b815260206004820152602560248201527f4552433732315073693a207175616e74697479206d7573742062652067726561604482015264074657220360dc1b6064820152608401610ac4565b6001600160a01b0383166136395760405162461bcd60e51b815260206004820152602360248201527f4552433732315073693a206d696e7420746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610ac4565b81600d600082825461364b91906144ed565b90915550506000818152600c6020526040902080546001600160a01b0319166001600160a01b038516179055613682600982612e02565b60008061368f84846144ed565b90506001600160a01b038516915082826000600080516020614afd833981519152600080a4600183015b8181146136df5780836000600080516020614afd833981519152600080a46001016136b9565b50610dc8565b60006040518061012001604052806101008152602001614b1d610100913960f87e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff61372e8561374f565b02901c81518110613741576137416148c4565b016020015160f81c92915050565b600080821161375d57600080fd5b5060008190031690565b828054613773906142b3565b90600052602060002090601f01602090048101928261379557600085556137db565b82601f106137ae57805160ff19168380011785556137db565b828001600101855582156137db579182015b828111156137db5782518255916020019190600101906137c0565b506137e79291506137eb565b5090565b5b808211156137e757600081556001016137ec565b803561ffff8116811461381257600080fd5b919050565b60008083601f84011261382957600080fd5b5081356001600160401b0381111561384057600080fd5b60208301915083602082850101111561385857600080fd5b9250929050565b80356001600160401b038116811461381257600080fd5b6000806000806000806080878903121561388f57600080fd5b61389887613800565b955060208701356001600160401b03808211156138b457600080fd5b6138c08a838b01613817565b90975095508591506138d460408a0161385f565b945060608901359150808211156138ea57600080fd5b506138f789828a01613817565b979a9699509497509295939492505050565b6001600160e01b031981168114611a1657600080fd5b60006020828403121561393157600080fd5b813561393c81613909565b9392505050565b60005b8381101561395e578181015183820152602001613946565b838111156119ab5750506000910152565b60008151808452613987816020860160208601613943565b601f01601f19169290920160200192915050565b60208152600061393c602083018461396f565b6000602082840312156139c057600080fd5b61393c82613800565b6000602082840312156139db57600080fd5b5035919050565b6001600160a01b0381168114611a1657600080fd5b8035613812816139e2565b60008060408385031215613a1557600080fd5b8235613a20816139e2565b946020939093013593505050565b600080600060608486031215613a4357600080fd5b8335613a4e816139e2565b92506020840135613a5e816139e2565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613aad57613aad613a6f565b604052919050565b60006001600160401b03821115613ace57613ace613a6f565b50601f01601f191660200190565b600082601f830112613aed57600080fd5b8135613b00613afb82613ab5565b613a85565b818152846020838601011115613b1557600080fd5b816020850160208301376000918101602001919091529392505050565b8035801515811461381257600080fd5b600080600080600060a08688031215613b5a57600080fd5b613b6386613800565b945060208601356001600160401b0380821115613b7f57600080fd5b613b8b89838a01613adc565b955060408801359450613ba060608901613b32565b93506080880135915080821115613bb657600080fd5b50613bc388828901613adc565b9150509295509295909350565b60008060408385031215613be357600080fd5b50508035926020909101359150565b60006001600160401b03821115613c0b57613c0b613a6f565b5060051b60200190565b600082601f830112613c2657600080fd5b81356020613c36613afb83613bf2565b82815260059290921b84018101918181019086841115613c5557600080fd5b8286015b84811015613c705780358352918301918301613c59565b509695505050505050565b60008060008060008060c08789031215613c9457600080fd5b613c9d87613800565b955060208701356001600160401b0380821115613cb957600080fd5b613cc58a838b01613adc565b96506040890135915080821115613cdb57600080fd5b613ce78a838b01613c15565b9550613cf560608a01613b32565b94506080890135915080821115613d0b57600080fd5b613d178a838b01613adc565b935060a0890135915080821115613d2d57600080fd5b50613d3a89828a01613adc565b9150509295509295509295565b600080600060408486031215613d5c57600080fd5b613d6584613800565b925060208401356001600160401b03811115613d8057600080fd5b613d8c86828701613817565b9497909650939450505050565b600080600080600060808688031215613db157600080fd5b613dba86613800565b945060208601356001600160401b03811115613dd557600080fd5b613de188828901613817565b9699909850959660408101359660609091013595509350505050565b600080600080600080600060e0888a031215613e1857600080fd5b8735613e23816139e2565b9650613e3160208901613800565b955060408801356001600160401b0380821115613e4d57600080fd5b613e598b838c01613adc565b965060608a0135955060808a01359150613e72826139e2565b90935060a089013590613e84826139e2565b90925060c08901359080821115613e9a57600080fd5b50613ea78a828b01613adc565b91505092959891949750929550565b600060208284031215613ec857600080fd5b813562ffffff8116811461393c57600080fd5b600080600060608486031215613ef057600080fd5b613ef984613800565b925060208401356001600160401b03811115613f1457600080fd5b613f2086828701613adc565b925050613f2f6040850161385f565b90509250925092565b600060208284031215613f4a57600080fd5b813561393c816139e2565b60008060408385031215613f6857600080fd5b613f7183613800565b9150613f7f60208401613800565b90509250929050565b600060208284031215613f9a57600080fd5b81356001600160401b03811115613fb057600080fd5b61240484828501613adc565b60008060408385031215613fcf57600080fd5b613a2083613800565b60008060408385031215613feb57600080fd5b8235613ff6816139e2565b9150613f7f60208401613b32565b6000806000806080858703121561401a57600080fd5b8435614025816139e2565b93506020850135614035816139e2565b92506040850135915060608501356001600160401b0381111561405757600080fd5b61406387828801613adc565b91505092959194509250565b60008060008060008060008060006101208a8c03121561408e57600080fd5b6140978a6139f7565b98506140a560208b01613800565b975060408a01356001600160401b03808211156140c157600080fd5b6140cd8d838e01613adc565b985060608c01359150808211156140e357600080fd5b6140ef8d838e01613c15565b97506140fd60808d016139f7565b965061410b60a08d016139f7565b955060c08c013591508082111561412157600080fd5b61412d8d838e01613adc565b945060e08c013591508082111561414357600080fd5b61414f8d838e01613adc565b93506101008c013591508082111561416657600080fd5b506141738c828d01613adc565b9150509295985092959850929598565b60008060008060006080868803121561419b57600080fd5b6141a486613800565b94506141b260208701613800565b93506040860135925060608601356001600160401b038111156141d457600080fd5b6141e088828901613817565b969995985093965092949392505050565b60008060006060848603121561420657600080fd5b61420f84613800565b925061421d60208501613800565b9150604084013590509250925092565b6000806040838503121561424057600080fd5b823561424b816139e2565b9150602083013561425b816139e2565b809150509250929050565b6000806000806080858703121561427c57600080fd5b61428585613800565b935061429360208601613800565b925060408501356142a3816139e2565b9396929550929360600135925050565b600181811c908216806142c757607f821691505b602082108114156130a857634e487b7160e01b600052602260045260246000fd5b8183823760009101908152919050565b6020808252601e908201527f4c7a4170703a2063616c6c6572206973206e6f7420746865206f776e65720000604082015260600190565b60208082526034908201527f4552433732315073693a207472616e736665722063616c6c6572206973206e6f6040820152731d081bdddb995c881b9bdc88185c1c1c9bdd995960621b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156143b3576143b3614383565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826143dd576143dd6143b8565b500490565b600081518084526020808501945080840160005b83811015614412578151875295820195908201906001016143f6565b509495945050505050565b608081526000614430608083018761396f565b8281036020840152614442818761396f565b9050828103604084015261445681866143e2565b9050828103606084015261446a818561396f565b979650505050505050565b61ffff861681526001600160a01b038516602082015260a0604082018190526000906144a39083018661396f565b841515606084015282810360808401526144bd818561396f565b98975050505050505050565b600080604083850312156144dc57600080fd5b505080516020909101519092909150565b6000821982111561450057614500614383565b500190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff8416815260406020820152600061220e604083018486614505565b8284823760609190911b6001600160601b0319169101908152601401919050565b600060001982141561458157614581614383565b5060010190565b600082601f83011261459957600080fd5b81516145a7613afb82613ab5565b8181528460208386010111156145bc57600080fd5b612404826020830160208701613943565b600080600080608085870312156145e357600080fd5b84516001600160401b03808211156145fa57600080fd5b61460688838901614588565b955060209150818701518181111561461d57600080fd5b61462989828a01614588565b95505060408701518181111561463e57600080fd5b8701601f8101891361464f57600080fd5b805161465d613afb82613bf2565b81815260059190911b8201840190848101908b83111561467c57600080fd5b928501925b8284101561469a57835182529285019290850190614681565b60608b01519097509450505050808211156146b457600080fd5b5061406387828801614588565b6000828210156146d3576146d3614383565b500390565b8054600090600181811c90808316806146f257607f831692505b602080841082141561471457634e487b7160e01b600052602260045260246000fd5b818015614728576001811461473957614766565b60ff19861689528489019650614766565b60008881526020902060005b8681101561475e5781548b820152908501908301614745565b505084890196505b50505050505092915050565b60008451614784818460208901613943565b614790818401866146d8565b9050602f60f81b815283516147ac816001840160208801613943565b64173539b7b760d91b6001929091019182015260060195945050505050565b600061ffff80881683528087166020840152508460408301526080606083015261446a608083018486614505565b61ffff86168152608060208201526000614817608083018688614505565b6001600160401b0394909416604083015250606001529392505050565b60008351614846818460208801613943565b61220e818401856146d8565b60006020828403121561486457600080fd5b81516001600160401b0381111561487a57600080fd5b61240484828501614588565b61ffff851681526080602082015260006148a3608083018661396f565b6001600160401b0385166040840152828103606084015261446a818561396f565b634e487b7160e01b600052603260045260246000fd5b600082516148ec818460208701613943565b9190910192915050565b60208152600061393c60208301846143e2565b828152604060208201526000612404604083018461396f565b61ffff8616815260a06020820152600061493f60a083018761396f565b6001600160a01b0386166040840152828103606084015261496081866143e2565b905082810360808401526144bd818561396f565b60208082526035908201527f4552433732315073693a207472616e7366657220746f206e6f6e20455243373260408201527418a932b1b2b4bb32b91034b6b83632b6b2b73a32b960591b606082015260800190565b6000826149d8576149d86143b8565b500690565b61ffff8616815260a0602082015260006149fa60a083018761396f565b6001600160401b03861660408401528281036060840152614960818661396f565b61ffff8716815260c060208201526000614a3860c083018861396f565b8281036040840152614a4a818861396f565b6001600160a01b0387811660608601528616608085015283810360a08501529050614a75818561396f565b9998505050505050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614ab59083018461396f565b9695505050505050565b600060208284031215614ad157600080fd5b815161393c8161390956fe8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ceddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a26469706673582212205419fe7d71e8c77355e02a9e369bccd3b08210e7c851dd210beebbe96d0cd76364736f6c6343000809003300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000f285e70ca2002b796a575e473285282bbf39d790000000000000000000000000000000000000000000000000000000000003d0900000000000000000000000003c2269811836af69497e5f486a85d7316753cf6200000000000000000000000000000000000000000000000000000000000000105a6b616c69656e204578706c6f7265720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035a4b580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003b6261666b726569677a346773623472326263756e736468377532736233717233686667646f6868796d73697774703271636177746b616d367264610000000000000000000000000000000000000000000000000000000000000000000000003b6261667962656966746d756f786e686c6d6d6f62666872616c6c69616233707471757764787033646a6979343261357067643236326f6d6a3335710000000000
Deployed Bytecode
0x60806040526004361061027a5760003560e01c80621d35671461027f57806301ffc9a7146102a157806306fdde03146102d657806307e0db17146102f8578063081812fc14610318578063095ea7b3146103505780630b4cad4c1461037057806310ddb1371461039057806318160ddd146103b057806322a3ecf9146103d357806323b872dd146104565780632a205e3d146104765780632a55205a146104ab5780632dd0066e146104ea5780633b5aeddb146104ff5780633d8b38f61461051f57806342842e0e1461053f57806342d65a8d1461055f57806346a438161461057f578063482881901461059f5780634ac3f4ff146105b557806351905636146105e257806352a284a2146105f55780635b8c41e6146106155780636352211e1461066457806366ad5c8a1461068457806370a08231146106a45780637533d788146106c45780638cfd8f5c146106e45780638da5cb5b1461071c5780638ffa1f2a1461073c57806395d89b411461075c5780639d5aef30146107715780639ea5d6b114610791578063a22cb465146107b1578063a2309ff8146107d1578063a5097ebf146107e6578063a6c3d165146107fb578063a7e0d43d1461081b578063af3fb21c1461083b578063b353aaa714610863578063b88d4fde14610897578063c145c54b146108b7578063c4461834146108ca578063c4ed6f58146108e0578063c87b56dd146108fb578063cbed8b9c1461091b578063d0ebdbe71461093b578063d12473a51461095b578063d1deba1f1461097b578063df2a5b3b1461098e578063e8a3d485146109ae578063e985e9c5146109c3578063f2fde38b146109e3578063f5ecbdbc14610a03578063fa25f9b614610a23575b600080fd5b34801561028b57600080fd5b5061029f61029a366004613876565b610a50565b005b3480156102ad57600080fd5b506102c16102bc36600461391f565b610c81565b60405190151581526020015b60405180910390f35b3480156102e257600080fd5b506102eb610c92565b6040516102cd919061399b565b34801561030457600080fd5b5061029f6103133660046139ae565b610d24565b34801561032457600080fd5b506103386103333660046139c9565b610dcf565b6040516001600160a01b0390911681526020016102cd565b34801561035c57600080fd5b5061029f61036b366004613a02565b610e5a565b34801561037c57600080fd5b5061029f61038b3660046139c9565b610f70565b34801561039c57600080fd5b5061029f6103ab3660046139ae565b610fac565b3480156103bc57600080fd5b506103c5611026565b6040519081526020016102cd565b3480156103df57600080fd5b506104276103ee3660046139c9565b60086020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b03909316602085015291830152151560608201526080016102cd565b34801561046257600080fd5b5061029f610471366004613a2e565b611035565b34801561048257600080fd5b50610496610491366004613b42565b611066565b604080519283526020830191909152016102cd565b3480156104b757600080fd5b506104cb6104c6366004613bd0565b61109c565b604080516001600160a01b0390931683526020830191909152016102cd565b3480156104f657600080fd5b506102eb6110f1565b34801561050b57600080fd5b5061049661051a366004613c7b565b61117f565b34801561052b57600080fd5b506102c161053a366004613d47565b611290565b34801561054b57600080fd5b5061029f61055a366004613a2e565b61135c565b34801561056b57600080fd5b5061029f61057a366004613d47565b611377565b34801561058b57600080fd5b5061029f61059a366004613d99565b61141f565b3480156105ab57600080fd5b506103c560055481565b3480156105c157600080fd5b506103c56105d03660046139ae565b60066020526000908152604090205481565b61029f6105f0366004613dfd565b6115a3565b34801561060157600080fd5b5061029f610610366004613eb6565b6115da565b34801561062157600080fd5b506103c5610630366004613edb565b6003602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b34801561067057600080fd5b5061033861067f3660046139c9565b611628565b34801561069057600080fd5b5061029f61069f366004613876565b61163c565b3480156106b057600080fd5b506103c56106bf366004613f38565b611718565b3480156106d057600080fd5b506102eb6106df3660046139ae565b6117e7565b3480156106f057600080fd5b506103c56106ff366004613f55565b600160209081526000928352604080842090915290825290205481565b34801561072857600080fd5b50600254610338906001600160a01b031681565b34801561074857600080fd5b5061029f610757366004613f88565b611800565b34801561076857600080fd5b506102eb6119b1565b34801561077d57600080fd5b5061029f61078c3660046139c9565b6119c0565b34801561079d57600080fd5b5061029f6107ac366004613fbc565b611a19565b3480156107bd57600080fd5b5061029f6107cc366004613fd8565b611a67565b3480156107dd57600080fd5b506103c5611b2b565b3480156107f257600080fd5b506102eb611b3b565b34801561080757600080fd5b5061029f610816366004613d47565b611b48565b34801561082757600080fd5b5061029f6108363660046139ae565b611be9565b34801561084757600080fd5b50610850600181565b60405161ffff90911681526020016102cd565b34801561086f57600080fd5b506103387f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf6281565b3480156108a357600080fd5b5061029f6108b2366004614004565b611c31565b61029f6108c536600461406f565b611c63565b3480156108d657600080fd5b506103c561271081565b3480156108ec57600080fd5b506004546108509061ffff1681565b34801561090757600080fd5b506102eb6109163660046139c9565b611c7f565b34801561092757600080fd5b5061029f610936366004614183565b611cbc565b34801561094757600080fd5b5061029f610956366004613f38565b611d68565b34801561096757600080fd5b5061029f610976366004613fbc565b611daf565b61029f610989366004613876565b611dfd565b34801561099a57600080fd5b5061029f6109a93660046141f1565b612013565b3480156109ba57600080fd5b506102eb6120ac565b3480156109cf57600080fd5b506102c16109de36600461422d565b6120dd565b3480156109ef57600080fd5b5061029f6109fe366004613f38565b61210b565b348015610a0f57600080fd5b506102eb610a1e366004614266565b612157565b348015610a2f57600080fd5b506103c5610a3e3660046139ae565b60076020526000908152604090205481565b336001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf621614610acd5760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526020819052604081208054610aeb906142b3565b80601f0160208091040260200160405190810160405280929190818152602001828054610b17906142b3565b8015610b645780601f10610b3957610100808354040283529160200191610b64565b820191906000526020600020905b815481529060010190602001808311610b4757829003601f168201915b50505050509050805186869050148015610b7f575060008151115b8015610ba7575080516020820120604051610b9d90889088906142e8565b6040518091039020145b610c025760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610ac4565b610c788787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061221792505050565b50505050505050565b6000610c8c82612290565b92915050565b6060600a8054610ca1906142b3565b80601f0160208091040260200160405190810160405280929190818152602001828054610ccd906142b3565b8015610d1a5780601f10610cef57610100808354040283529160200191610d1a565b820191906000526020600020905b815481529060010190602001808311610cfd57829003601f168201915b5050505050905090565b6002546001600160a01b03163314610d4e5760405162461bcd60e51b8152600401610ac4906142f8565b6040516307e0db1760e01b815261ffff821660048201527f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b0316906307e0db17906024015b600060405180830381600087803b158015610db457600080fd5b505af1158015610dc8573d6000803e3d6000fd5b5050505050565b6000610dda826122b5565b610e3e5760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a20617070726f76656420717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610ac4565b506000908152600e60205260409020546001600160a01b031690565b6000610e6582611628565b9050806001600160a01b0316836001600160a01b03161415610ed55760405162461bcd60e51b8152602060048201526024808201527f4552433732315073693a20617070726f76616c20746f2063757272656e74206f6044820152633bb732b960e11b6064820152608401610ac4565b336001600160a01b0382161480610ef15750610ef181336120dd565b610f615760405162461bcd60e51b815260206004820152603b60248201527f4552433732315073693a20617070726f76652063616c6c6572206973206e6f7460448201527a081bdddb995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b602a1b6064820152608401610ac4565b610f6b83836122d1565b505050565b6002546001600160a01b03163314610f9a5760405162461bcd60e51b8152600401610ac4906142f8565b60008111610fa757600080fd5b600555565b6002546001600160a01b03163314610fd65760405162461bcd60e51b8152600401610ac4906142f8565b6040516310ddb13760e01b815261ffff821660048201527f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b0316906310ddb13790602401610d9a565b6000611030611b2b565b905090565b61103f338261233f565b61105b5760405162461bcd60e51b8152600401610ac49061432f565b610f6b83838361240c565b60008061108e8787611077886125e4565b87876040518060200160405280600081525061117f565b915091509550959350505050565b604080518082019091526012546001600160a01b038116808352600160a01b90910462ffffff16602083018190529091600091612710906110dd9086614399565b6110e791906143ce565b9150509250929050565b601180546110fe906142b3565b80601f016020809104026020016040519081016040528092919081815260200182805461112a906142b3565b80156111775780601f1061114c57610100808354040283529160200191611177565b820191906000526020600020905b81548152906001019060200180831161115a57829003601f168201915b505050505081565b60008060008788888660405160200161119b949392919061441d565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf6216906340a7bb10906111ff908c90309086908c908c90600401614475565b604080518083038186803b15801561121657600080fd5b505afa15801561122a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124e91906144c9565b60045491945092506000906127109061126b9061ffff1686614399565b61127591906143ce565b905061128181856144ed565b93505050965096945050505050565b61ffff8316600090815260208190526040812080548291906112b1906142b3565b80601f01602080910402602001604051908101604052809291908181526020018280546112dd906142b3565b801561132a5780601f106112ff5761010080835404028352916020019161132a565b820191906000526020600020905b81548152906001019060200180831161130d57829003601f168201915b5050505050905083836040516113419291906142e8565b60405180910390208180519060200120149150509392505050565b610f6b83838360405180602001604052806000815250611c31565b6002546001600160a01b031633146113a15760405162461bcd60e51b8152600401610ac4906142f8565b6040516342d65a8d60e01b81526001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf6216906342d65a8d906113f19086908690869060040161452e565b600060405180830381600087803b15801561140b57600080fd5b505af1158015610c78573d6000803e3d6000fd5b6002546001600160a01b031633146114495760405162461bcd60e51b8152600401610ac4906142f8565b600082116114a55760405162461bcd60e51b815260206004820152602360248201527f647374436861696e4964546f5472616e73666572476173206d7573742062652060448201526203e20360ec1b6064820152608401610ac4565b61ffff85166000908152600760205260409020829055806115135760405162461bcd60e51b815260206004820152602260248201527f647374436861696e4964546f42617463684c696d6974206d757374206265203e604482015261020360f41b6064820152608401610ac4565b61ffff8516600090815260066020908152604091829020839055905161153f918691869130910161454c565b60408051601f1981840301815291815261ffff871660009081526020818152919020825161157293919290910190613767565b50600080516020614add8339815191528585856040516115949392919061452e565b60405180910390a15050505050565b610c788787876115b2886125e4565b878787604051806020016040528060008152506040518060200160405280600081525061262f565b6002546001600160a01b031633146116045760405162461bcd60e51b8152600401610ac4906142f8565b6012805462ffffff909216600160a01b0262ffffff60a01b19909216919091179055565b6000806116348361280b565b509392505050565b33301461169a5760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610ac4565b6117108686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8901819004810282018101909252878152899350915087908790819084018382808284376000920191909152506128a292505050565b505050505050565b60006001600160a01b0382166117865760405162461bcd60e51b815260206004820152602d60248201527f4552433732315073693a2062616c616e636520717565727920666f722074686560448201526c207a65726f206164647265737360981b6064820152608401610ac4565b6000805b600d548110156117e05761179d816122b5565b156117d0576117ab81611628565b6001600160a01b0316846001600160a01b031614156117d0576117cd8261456d565b91505b6117d98161456d565b905061178a565b5092915050565b600060208190529081526040902080546110fe906142b3565b80516020808301919091206000818152600890925260409091206002015460ff1661182a57600080fd5b60008280602001905181019061184091906145cd565b506000858152600860205260408120805460019091015492955090935061187f925061ffff811691620100009091046001600160a01b03169085612af2565b600084815260086020526040902060010154909150811161189f57600080fd5b81518114156119175760008381526008602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba2339061190a9085815260200190565b60405180910390a16119ab565b60408051608081018252600085815260086020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b50505050565b6060600b8054610ca1906142b3565b6002546001600160a01b031633146119ea5760405162461bcd60e51b8152600401610ac4906142f8565b6127106119f5611026565b1115611a0057600080fd5b600254611a16906001600160a01b031682612b44565b50565b6002546001600160a01b03163314611a435760405162461bcd60e51b8152600401610ac4906142f8565b60008111611a5057600080fd5b61ffff909116600090815260066020526040902055565b6001600160a01b038216331415611abf5760405162461bcd60e51b815260206004820152601c60248201527b22a9219b9918a839b49d1030b8383937bb32903a379031b0b63632b960211b6044820152606401610ac4565b336000818152600f602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600080600d5461103091906146c1565b601080546110fe906142b3565b6002546001600160a01b03163314611b725760405162461bcd60e51b8152600401610ac4906142f8565b818130604051602001611b879392919061454c565b60408051601f1981840301815291815261ffff8516600090815260208181529190208251611bba93919290910190613767565b50600080516020614add833981519152838383604051611bdc9392919061452e565b60405180910390a1505050565b6004546201000090046001600160a01b03163314611c0657600080fd5b6127108161ffff161115611c1957600080fd5b6004805461ffff191661ffff92909216919091179055565b611c3b338361233f565b611c575760405162461bcd60e51b8152600401610ac49061432f565b6119ab84848484612b62565b611c7489898989898989898961262f565b505050505050505050565b6060611c89612b97565b6011611c9484612bb8565b604051602001611ca693929190614772565b6040516020818303038152906040529050919050565b6002546001600160a01b03163314611ce65760405162461bcd60e51b8152600401610ac4906142f8565b6040516332fb62e760e21b81526001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf62169063cbed8b9c90611d3a90889088908890889088906004016147cb565b600060405180830381600087803b158015611d5457600080fd5b505af1158015611c74573d6000803e3d6000fd5b6004546201000090046001600160a01b03163314611d8557600080fd5b600480546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6002546001600160a01b03163314611dd95760405162461bcd60e51b8152600401610ac4906142f8565b60008111611de657600080fd5b61ffff909116600090815260076020526040902055565b61ffff86166000908152600360205260408082209051611e2090889088906142e8565b90815260408051602092819003830190206001600160401b03871660009081529252902054905080611ea05760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610ac4565b808383604051611eb19291906142e8565b604051809103902014611f105760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610ac4565b61ffff87166000908152600360205260408082209051611f3390899089906142e8565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f88018290048202830182019052868252611fcb918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a9350915088908890819084018382808284376000920191909152506128a292505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e587878787856040516120029594939291906147f9565b60405180910390a150505050505050565b6002546001600160a01b0316331461203d5760405162461bcd60e51b8152600401610ac4906142f8565b6000811161204a57600080fd5b61ffff83811660008181526001602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611bdc565b60606120b6612b97565b60106040516020016120c9929190614834565b604051602081830303815290604052905090565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205460ff1690565b6002546001600160a01b031633146121355760405162461bcd60e51b8152600401610ac4906142f8565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b03169063f5ecbdbc9060840160006040518083038186803b1580156121d257600080fd5b505afa1580156121e6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261220e9190810190614852565b95945050505050565b60008061227a5a60966366ad5c8a60e01b8989898960405160240161223f9493929190614886565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915230929190612cb5565b9150915081611710576117108686868685612d3f565b60006001600160e01b031982166380ac58cd60e01b1480610c8c5750610c8c82612dcd565b60006122c0600d5490565b82108015610c8c5750600192915050565b6000818152600e6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061230682611628565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061234a826122b5565b6123ae5760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a206f70657261746f7220717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610ac4565b60006123b983611628565b9050806001600160a01b0316846001600160a01b031614806123f45750836001600160a01b03166123e984610dcf565b6001600160a01b0316145b80612404575061240481856120dd565b949350505050565b6000806124188361280b565b91509150846001600160a01b0316826001600160a01b0316146124925760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a207472616e73666572206f6620746f6b656e2074686160448201526b3a1034b9903737ba1037bbb760a11b6064820152608401610ac4565b6001600160a01b0384166124f85760405162461bcd60e51b815260206004820152602760248201527f4552433732315073693a207472616e7366657220746f20746865207a65726f206044820152666164647265737360c81b6064820152608401610ac4565b6125036000846122d1565b60006125108460016144ed565b600881901c600090815260096020526040902054909150600160ff1b60ff83161c161580156125405750600d5481105b15612577576000818152600c6020526040902080546001600160a01b0319166001600160a01b038816179055612577600982612e02565b6000848152600c6020526040902080546001600160a01b0319166001600160a01b0387161790558184146125b0576125b0600985612e02565b83856001600160a01b0316876001600160a01b0316600080516020614afd83398151915260405160405180910390a4611710565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061261e5761261e6148c4565b602090810291909101015292915050565b60008651116126765760405162461bcd60e51b8152602060048201526013602482015272746f6b656e4964735b5d20697320656d70747960681b6044820152606401610ac4565b61ffff8816600090815260066020526040902054865111156126e55760405162461bcd60e51b815260206004820152602260248201527f62617463682073697a65206578636565647320647374206261746368206c696d6044820152611a5d60f21b6064820152608401610ac4565b60005b8651811015612728576127168a8a8a8a8581518110612709576127096148c4565b6020026020010151612e2e565b806127208161456d565b9150506126e8565b50600087838884604051602001612742949392919061441d565b6040516020818303038152906040529050612787896001868a51600760008f61ffff1661ffff168152602001908152602001600020546127829190614399565b612f02565b600061279234612fdc565b90506127a28a83898989866130ae565b886040516127b091906148da565b60405180910390208b6001600160a01b03168b61ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a8b6040516127f691906148f6565b60405180910390a45050505050505050505050565b600080612817836122b5565b6128785760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a206f776e657220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ac4565b61288183613249565b6000818152600c60205260409020546001600160a01b031694909350915050565b600080600080848060200190518101906128bc91906145cd565b6014840151602884015194985092965090945092509060006128e08b848388612af2565b905084518110156129f35760008880519060200120905060405180608001604052808d61ffff168152602001856001600160a01b03168152602001838152602001600115158152506008600083815260200190815260200160002060008201518160000160006101000a81548161ffff021916908361ffff16021790555060208201518160000160026101000a8154816001600160a01b0302191690836001600160a01b031602179055506040820151816001015560608201518160020160006101000a81548160ff0219169083151502179055509050507f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad7818a6040516129e9929190614909565b60405180910390a1505b826001600160a01b03168a604051612a0b91906148da565b60405180910390208c61ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d99026588604051612a4791906148f6565b60405180910390a4845181148015612a6757506001600160a01b03821615155b15612ae55760405163bace587f60e01b81528b908b9085908590899089906001600160a01b0384169063bace587f90612aac9089908990899088908890600401614922565b600060405180830381600087803b158015612ac657600080fd5b505af1158015612ada573d6000803e3d6000fd5b505050505050505050505b5050505050505050505050565b6000825b825181101561220e576005545a1015612b0e5761220e565b612b328686858481518110612b2557612b256148c4565b6020026020010151613256565b80612b3c8161456d565b915050612af6565b612b5e8282604051806020016040528060008152506132b6565b5050565b612b6d84848461240c565b612b7b8484846001856132d7565b6119ab5760405162461bcd60e51b8152600401610ac490614974565b604080518082019091526007815266697066733a2f2f60c81b602082015290565b606081612bdc5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612c065780612bf08161456d565b9150612bff9050600a836143ce565b9150612be0565b6000816001600160401b03811115612c2057612c20613a6f565b6040519080825280601f01601f191660200182016040528015612c4a576020820181803683370190505b5090505b841561240457612c5f6001836146c1565b9150612c6c600a866149c9565b612c779060306144ed565b60f81b818381518110612c8c57612c8c6148c4565b60200101906001600160f81b031916908160001a905350612cae600a866143ce565b9450612c4e565b6000606060008060008661ffff166001600160401b03811115612cda57612cda613a6f565b6040519080825280601f01601f191660200182016040528015612d04576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115612d26578692505b828152826000602083013e909890975095505050505050565b8180519060200120600360008761ffff1661ffff16815260200190815260200160002085604051612d7091906148da565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c9061159490879087908790879087906149dd565b60006001600160e01b031982166381af209b60e01b1480610c8c57506301ffc9a760e01b6001600160e01b0319831614610c8c565b600881901c600090815260209290925260409091208054600160ff1b60ff9093169290921c9091179055565b612e38338261233f565b612e925760405162461bcd60e51b815260206004820152602560248201527f73656e642063616c6c6572206973206e6f74206f776e6572206e6f72206170706044820152641c9bdd995960da1b6064820152608401610ac4565b836001600160a01b0316612ea582611628565b6001600160a01b031614612ef75760405162461bcd60e51b815260206004820152601960248201527839b2b73210333937b69034b731b7b93932b1ba1037bbb732b960391b6044820152606401610ac4565b6119ab84308361240c565b6000612f0d83613419565b61ffff808716600090815260016020908152604080832093891683529290529081205491925090612f3f9084906144ed565b905060008111612f8e5760405162461bcd60e51b815260206004820152601a602482015279131e905c1c0e881b5a5b91d85cd31a5b5a5d081b9bdd081cd95d60321b6044820152606401610ac4565b808210156117105760405162461bcd60e51b815260206004820152601b60248201527a4c7a4170703a20676173206c696d697420697320746f6f206c6f7760281b6044820152606401610ac4565b600454600090819061271090612ff69061ffff1685614399565b61300091906143ce565b905061300c81846146c1565b915080156130a8576004546040516000916201000090046001600160a01b03169083908381818185875af1925050503d8060008114613067576040519150601f19603f3d011682016040523d82523d6000602084013e61306c565b606091505b50509050806130a65760405162461bcd60e51b8152600401610ac4906020808252600490820152632166656560e01b604082015260600190565b505b50919050565b61ffff8616600090815260208190526040812080546130cc906142b3565b80601f01602080910402602001604051908101604052809291908181526020018280546130f8906142b3565b80156131455780601f1061311a57610100808354040283529160200191613145565b820191906000526020600020905b81548152906001019060200180831161312857829003601f168201915b505050505090508051600014156131b75760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610ac4565b60405162c5803160e81b81526001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf62169063c580310090849061320e908b9086908c908c908c908c90600401614a1b565b6000604051808303818588803b15801561322757600080fd5b505af115801561323b573d6000803e3d6000fd5b505050505050505050505050565b6000610c8c600983613474565b61325f816122b5565b158061328b575061326f816122b5565b801561328b57503061328082611628565b6001600160a01b0316145b61329457600080fd5b61329d816122b5565b6132ab57610f6b8282612b44565b610f6b30838361240c565b60006132c1600d5490565b90506132cd848461356c565b612b7b6000858386865b60006001600160a01b0385163b1561340d57506001835b6132f884866144ed565b81101561340757604051630a85bd0160e11b81526001600160a01b0387169063150b7a02906133319033908b9086908990600401614a82565b602060405180830381600087803b15801561334b57600080fd5b505af192505050801561337b575060408051601f3d908101601f1916820190925261337891810190614abf565b60015b6133d5573d8080156133a9576040519150601f19603f3d011682016040523d82523d6000602084013e6133ae565b606091505b5080516133cd5760405162461bcd60e51b8152600401610ac490614974565b805181602001fd5b8280156133f257506001600160e01b03198116630a85bd0160e11b145b925050806133ff8161456d565b9150506132ee565b5061220e565b50600195945050505050565b600060228251101561346c5760405162461bcd60e51b815260206004820152601c60248201527b4c7a4170703a20696e76616c69642061646170746572506172616d7360201b6044820152606401610ac4565b506022015190565b600881901c60008181526020849052604081205490919060ff808516919082181c80156134b6576134a4816136e5565b60ff168203600884901b179350613563565b600083116135235760405162461bcd60e51b815260206004820152603460248201527f4269744d6170733a205468652073657420626974206265666f7265207468652060448201527334b73232bc103237b2b9b713ba1032bc34b9ba1760611b6064820152608401610ac4565b50600019909101600081815260208690526040902054909190801561355e5761354b816136e5565b60ff0360ff16600884901b179350613563565b6134b6565b50505092915050565b6000613577600d5490565b9050600082116135d75760405162461bcd60e51b815260206004820152602560248201527f4552433732315073693a207175616e74697479206d7573742062652067726561604482015264074657220360dc1b6064820152608401610ac4565b6001600160a01b0383166136395760405162461bcd60e51b815260206004820152602360248201527f4552433732315073693a206d696e7420746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610ac4565b81600d600082825461364b91906144ed565b90915550506000818152600c6020526040902080546001600160a01b0319166001600160a01b038516179055613682600982612e02565b60008061368f84846144ed565b90506001600160a01b038516915082826000600080516020614afd833981519152600080a4600183015b8181146136df5780836000600080516020614afd833981519152600080a46001016136b9565b50610dc8565b60006040518061012001604052806101008152602001614b1d610100913960f87e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff61372e8561374f565b02901c81518110613741576137416148c4565b016020015160f81c92915050565b600080821161375d57600080fd5b5060008190031690565b828054613773906142b3565b90600052602060002090601f01602090048101928261379557600085556137db565b82601f106137ae57805160ff19168380011785556137db565b828001600101855582156137db579182015b828111156137db5782518255916020019190600101906137c0565b506137e79291506137eb565b5090565b5b808211156137e757600081556001016137ec565b803561ffff8116811461381257600080fd5b919050565b60008083601f84011261382957600080fd5b5081356001600160401b0381111561384057600080fd5b60208301915083602082850101111561385857600080fd5b9250929050565b80356001600160401b038116811461381257600080fd5b6000806000806000806080878903121561388f57600080fd5b61389887613800565b955060208701356001600160401b03808211156138b457600080fd5b6138c08a838b01613817565b90975095508591506138d460408a0161385f565b945060608901359150808211156138ea57600080fd5b506138f789828a01613817565b979a9699509497509295939492505050565b6001600160e01b031981168114611a1657600080fd5b60006020828403121561393157600080fd5b813561393c81613909565b9392505050565b60005b8381101561395e578181015183820152602001613946565b838111156119ab5750506000910152565b60008151808452613987816020860160208601613943565b601f01601f19169290920160200192915050565b60208152600061393c602083018461396f565b6000602082840312156139c057600080fd5b61393c82613800565b6000602082840312156139db57600080fd5b5035919050565b6001600160a01b0381168114611a1657600080fd5b8035613812816139e2565b60008060408385031215613a1557600080fd5b8235613a20816139e2565b946020939093013593505050565b600080600060608486031215613a4357600080fd5b8335613a4e816139e2565b92506020840135613a5e816139e2565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613aad57613aad613a6f565b604052919050565b60006001600160401b03821115613ace57613ace613a6f565b50601f01601f191660200190565b600082601f830112613aed57600080fd5b8135613b00613afb82613ab5565b613a85565b818152846020838601011115613b1557600080fd5b816020850160208301376000918101602001919091529392505050565b8035801515811461381257600080fd5b600080600080600060a08688031215613b5a57600080fd5b613b6386613800565b945060208601356001600160401b0380821115613b7f57600080fd5b613b8b89838a01613adc565b955060408801359450613ba060608901613b32565b93506080880135915080821115613bb657600080fd5b50613bc388828901613adc565b9150509295509295909350565b60008060408385031215613be357600080fd5b50508035926020909101359150565b60006001600160401b03821115613c0b57613c0b613a6f565b5060051b60200190565b600082601f830112613c2657600080fd5b81356020613c36613afb83613bf2565b82815260059290921b84018101918181019086841115613c5557600080fd5b8286015b84811015613c705780358352918301918301613c59565b509695505050505050565b60008060008060008060c08789031215613c9457600080fd5b613c9d87613800565b955060208701356001600160401b0380821115613cb957600080fd5b613cc58a838b01613adc565b96506040890135915080821115613cdb57600080fd5b613ce78a838b01613c15565b9550613cf560608a01613b32565b94506080890135915080821115613d0b57600080fd5b613d178a838b01613adc565b935060a0890135915080821115613d2d57600080fd5b50613d3a89828a01613adc565b9150509295509295509295565b600080600060408486031215613d5c57600080fd5b613d6584613800565b925060208401356001600160401b03811115613d8057600080fd5b613d8c86828701613817565b9497909650939450505050565b600080600080600060808688031215613db157600080fd5b613dba86613800565b945060208601356001600160401b03811115613dd557600080fd5b613de188828901613817565b9699909850959660408101359660609091013595509350505050565b600080600080600080600060e0888a031215613e1857600080fd5b8735613e23816139e2565b9650613e3160208901613800565b955060408801356001600160401b0380821115613e4d57600080fd5b613e598b838c01613adc565b965060608a0135955060808a01359150613e72826139e2565b90935060a089013590613e84826139e2565b90925060c08901359080821115613e9a57600080fd5b50613ea78a828b01613adc565b91505092959891949750929550565b600060208284031215613ec857600080fd5b813562ffffff8116811461393c57600080fd5b600080600060608486031215613ef057600080fd5b613ef984613800565b925060208401356001600160401b03811115613f1457600080fd5b613f2086828701613adc565b925050613f2f6040850161385f565b90509250925092565b600060208284031215613f4a57600080fd5b813561393c816139e2565b60008060408385031215613f6857600080fd5b613f7183613800565b9150613f7f60208401613800565b90509250929050565b600060208284031215613f9a57600080fd5b81356001600160401b03811115613fb057600080fd5b61240484828501613adc565b60008060408385031215613fcf57600080fd5b613a2083613800565b60008060408385031215613feb57600080fd5b8235613ff6816139e2565b9150613f7f60208401613b32565b6000806000806080858703121561401a57600080fd5b8435614025816139e2565b93506020850135614035816139e2565b92506040850135915060608501356001600160401b0381111561405757600080fd5b61406387828801613adc565b91505092959194509250565b60008060008060008060008060006101208a8c03121561408e57600080fd5b6140978a6139f7565b98506140a560208b01613800565b975060408a01356001600160401b03808211156140c157600080fd5b6140cd8d838e01613adc565b985060608c01359150808211156140e357600080fd5b6140ef8d838e01613c15565b97506140fd60808d016139f7565b965061410b60a08d016139f7565b955060c08c013591508082111561412157600080fd5b61412d8d838e01613adc565b945060e08c013591508082111561414357600080fd5b61414f8d838e01613adc565b93506101008c013591508082111561416657600080fd5b506141738c828d01613adc565b9150509295985092959850929598565b60008060008060006080868803121561419b57600080fd5b6141a486613800565b94506141b260208701613800565b93506040860135925060608601356001600160401b038111156141d457600080fd5b6141e088828901613817565b969995985093965092949392505050565b60008060006060848603121561420657600080fd5b61420f84613800565b925061421d60208501613800565b9150604084013590509250925092565b6000806040838503121561424057600080fd5b823561424b816139e2565b9150602083013561425b816139e2565b809150509250929050565b6000806000806080858703121561427c57600080fd5b61428585613800565b935061429360208601613800565b925060408501356142a3816139e2565b9396929550929360600135925050565b600181811c908216806142c757607f821691505b602082108114156130a857634e487b7160e01b600052602260045260246000fd5b8183823760009101908152919050565b6020808252601e908201527f4c7a4170703a2063616c6c6572206973206e6f7420746865206f776e65720000604082015260600190565b60208082526034908201527f4552433732315073693a207472616e736665722063616c6c6572206973206e6f6040820152731d081bdddb995c881b9bdc88185c1c1c9bdd995960621b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156143b3576143b3614383565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826143dd576143dd6143b8565b500490565b600081518084526020808501945080840160005b83811015614412578151875295820195908201906001016143f6565b509495945050505050565b608081526000614430608083018761396f565b8281036020840152614442818761396f565b9050828103604084015261445681866143e2565b9050828103606084015261446a818561396f565b979650505050505050565b61ffff861681526001600160a01b038516602082015260a0604082018190526000906144a39083018661396f565b841515606084015282810360808401526144bd818561396f565b98975050505050505050565b600080604083850312156144dc57600080fd5b505080516020909101519092909150565b6000821982111561450057614500614383565b500190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff8416815260406020820152600061220e604083018486614505565b8284823760609190911b6001600160601b0319169101908152601401919050565b600060001982141561458157614581614383565b5060010190565b600082601f83011261459957600080fd5b81516145a7613afb82613ab5565b8181528460208386010111156145bc57600080fd5b612404826020830160208701613943565b600080600080608085870312156145e357600080fd5b84516001600160401b03808211156145fa57600080fd5b61460688838901614588565b955060209150818701518181111561461d57600080fd5b61462989828a01614588565b95505060408701518181111561463e57600080fd5b8701601f8101891361464f57600080fd5b805161465d613afb82613bf2565b81815260059190911b8201840190848101908b83111561467c57600080fd5b928501925b8284101561469a57835182529285019290850190614681565b60608b01519097509450505050808211156146b457600080fd5b5061406387828801614588565b6000828210156146d3576146d3614383565b500390565b8054600090600181811c90808316806146f257607f831692505b602080841082141561471457634e487b7160e01b600052602260045260246000fd5b818015614728576001811461473957614766565b60ff19861689528489019650614766565b60008881526020902060005b8681101561475e5781548b820152908501908301614745565b505084890196505b50505050505092915050565b60008451614784818460208901613943565b614790818401866146d8565b9050602f60f81b815283516147ac816001840160208801613943565b64173539b7b760d91b6001929091019182015260060195945050505050565b600061ffff80881683528087166020840152508460408301526080606083015261446a608083018486614505565b61ffff86168152608060208201526000614817608083018688614505565b6001600160401b0394909416604083015250606001529392505050565b60008351614846818460208801613943565b61220e818401856146d8565b60006020828403121561486457600080fd5b81516001600160401b0381111561487a57600080fd5b61240484828501614588565b61ffff851681526080602082015260006148a3608083018661396f565b6001600160401b0385166040840152828103606084015261446a818561396f565b634e487b7160e01b600052603260045260246000fd5b600082516148ec818460208701613943565b9190910192915050565b60208152600061393c60208301846143e2565b828152604060208201526000612404604083018461396f565b61ffff8616815260a06020820152600061493f60a083018761396f565b6001600160a01b0386166040840152828103606084015261496081866143e2565b905082810360808401526144bd818561396f565b60208082526035908201527f4552433732315073693a207472616e7366657220746f206e6f6e20455243373260408201527418a932b1b2b4bb32b91034b6b83632b6b2b73a32b960591b606082015260800190565b6000826149d8576149d86143b8565b500690565b61ffff8616815260a0602082015260006149fa60a083018761396f565b6001600160401b03861660408401528281036060840152614960818661396f565b61ffff8716815260c060208201526000614a3860c083018861396f565b8281036040840152614a4a818861396f565b6001600160a01b0387811660608601528616608085015283810360a08501529050614a75818561396f565b9998505050505050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614ab59083018461396f565b9695505050505050565b600060208284031215614ad157600080fd5b815161393c8161390956fe8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ceddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a26469706673582212205419fe7d71e8c77355e02a9e369bccd3b08210e7c851dd210beebbe96d0cd76364736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000f285e70ca2002b796a575e473285282bbf39d790000000000000000000000000000000000000000000000000000000000003d0900000000000000000000000003c2269811836af69497e5f486a85d7316753cf6200000000000000000000000000000000000000000000000000000000000000105a6b616c69656e204578706c6f7265720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035a4b580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003b6261666b726569677a346773623472326263756e736468377532736233717233686667646f6868796d73697774703271636177746b616d367264610000000000000000000000000000000000000000000000000000000000000000000000003b6261667962656966746d756f786e686c6d6d6f62666872616c6c69616233707471757764787033646a6979343261357067643236326f6d6a3335710000000000
-----Decoded View---------------
Arg [0] : _name (string): Zkalien Explorer
Arg [1] : _symbol (string): ZKX
Arg [2] : _collectionURI (string): bafkreigz4gsb4r2bcunsdh7u2sb3qr3hfgdohhymsiwtp2qcawtkam6rda
Arg [3] : _tokensURI (string): bafybeiftmuoxnhlmmobfhralliab3ptquwdxp3djiy42a5pgd262omj35q
Arg [4] : _owner (address): 0xF285E70Ca2002b796A575E473285282BBf39D790
Arg [5] : _minGasToTransfer (uint256): 250000
Arg [6] : _lzEndpoint (address): 0x3c2269811836af69497E5F486A85D7316753cf62
-----Encoded View---------------
17 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [3] : 00000000000000000000000000000000000000000000000000000000000001c0
Arg [4] : 000000000000000000000000f285e70ca2002b796a575e473285282bbf39d790
Arg [5] : 000000000000000000000000000000000000000000000000000000000003d090
Arg [6] : 0000000000000000000000003c2269811836af69497e5f486a85d7316753cf62
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000010
Arg [8] : 5a6b616c69656e204578706c6f72657200000000000000000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [10] : 5a4b580000000000000000000000000000000000000000000000000000000000
Arg [11] : 000000000000000000000000000000000000000000000000000000000000003b
Arg [12] : 6261666b726569677a346773623472326263756e736468377532736233717233
Arg [13] : 686667646f6868796d73697774703271636177746b616d367264610000000000
Arg [14] : 000000000000000000000000000000000000000000000000000000000000003b
Arg [15] : 6261667962656966746d756f786e686c6d6d6f62666872616c6c696162337074
Arg [16] : 71757764787033646a6979343261357067643236326f6d6a3335710000000000
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.