ERC-721
Overview
Max Total Supply
3,333 DragonMolly
Holders
771
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 DragonMollyLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
DragonMolly
Compiler Version
v0.8.0+commit.c7dfd78e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract DragonMolly is ERC721, Ownable { using Strings for uint256; using ECDSA for bytes32; uint256 public MAX_PRESALE = 1111; uint256 public MAX_FREE = 1000; uint256 public maxSupply = 6666; uint256 public currentSupply = 0; uint256 public maxPerWallet = 5; uint256 public salePrice = 0.1 ether; uint256 public presalePrice = 0.03 ether; uint256 public presaleCount; uint256 public freeMinted; //Placeholders address private presaleAddress = address(0x41451D6448082c4Bb1dED8f7991b02f60738017a); address private freeAddress = address(0xaABc53116F0B995BDe9D61556Ef3492043eDbF99); address private wallet = address(0x54F22E10Bc5a24B42cb22b1cDdB545aa448d6F35); string private baseURI; string private notRevealedUri = "ipfs://QmcmyqYcBubUpK2NjXv4K1WDfDefBVP27ikQ9KE5U9Qt4B"; bool public revealed = false; bool public baseLocked = false; bool public marketOpened = false; bool public freeMintOpened = false; enum WorkflowStatus { Before, Presale, Sale, Paused, Reveal } WorkflowStatus public workflow; mapping(address => uint256) public freeMintAccess; mapping(address => uint256) public presaleMintLog; mapping(address => uint256) public publicMintLog; mapping(address => uint256) public freeMintLog; constructor() ERC721("Dragon Molly", "DragonMolly") { transferOwnership(msg.sender); workflow = WorkflowStatus.Before; initFree(); } function setApprovalForAll(address operator, bool approved) public virtual override { require(marketOpened, 'The sale of NFTs on the marketplaces has not been opened yet.'); _setApprovalForAll(_msgSender(), operator, approved); } function approve(address to, uint256 tokenId) public virtual override { require(marketOpened, 'The sale of NFTs on the marketplaces has not been opened yet.'); address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } function withdraw() public onlyOwner { uint256 _balance = address( this ).balance; payable( wallet ).transfer( _balance ); } //GETTERS function getSaleStatus() public view returns (WorkflowStatus) { return workflow; } function totalSupply() public view returns (uint256) { return currentSupply; } function getFreeMintAmount( address _acc ) public view returns (uint256) { return freeMintAccess[ _acc ]; } function getFreeMintLog( address _acc ) public view returns (uint256) { return freeMintLog[ _acc ]; } function validateSignature( address _addr, bytes memory _s ) internal view returns (bool){ bytes32 messageHash = keccak256( abi.encodePacked( address(this), msg.sender) ); address signer = messageHash.toEthSignedMessageHash().recover(_s); if( _addr == signer ) { return true; } else { return false; } } //Batch minting function mintBatch( address to, uint256 baseId, uint256 number ) internal { for (uint256 i = 0; i < number; i++) { _safeMint(to, baseId + i); } } /** Claims tokens for free paying only gas fees */ function freeMint(uint256 _amount, bytes calldata signature) external { //Free mint check require( freeMintOpened, "Free mint is not opened yet." ); //Check free mint signature require( validateSignature( freeAddress, signature ), "SIGNATURE_VALIDATION_FAILED" ); uint256 supply = currentSupply; uint256 allowedAmount = 1; if( freeMintAccess[ msg.sender ] > 0 ) { allowedAmount = freeMintAccess[ msg.sender ]; } require( freeMintLog[ msg.sender ] + _amount <= allowedAmount, "You dont have permision to free mint that amount." ); require( supply + _amount <= maxSupply, "Molly: Mint too large, exceeding the maxSupply" ); require( freeMinted + _amount <= MAX_FREE, "Molly: Mint too large, exceeding the free mint amount" ); freeMintLog[ msg.sender ] += _amount; freeMinted += _amount; currentSupply += _amount; mintBatch(msg.sender, supply, _amount); } function presaleMint( uint256 amount, bytes calldata signature ) external payable { require( workflow == WorkflowStatus.Presale, "Molly: Presale is not currently active." ); require( validateSignature( presaleAddress, signature ), "SIGNATURE_VALIDATION_FAILED" ); require(amount > 0, "You must mint at least one token"); //Max per wallet check require( presaleMintLog[ msg.sender ] + amount <= maxPerWallet, "Molly: You have exceeded the max per wallet amount!" ); //Price check require( msg.value >= presalePrice * amount, "Molly: Insuficient ETH amount sent." ); require( presaleCount + amount <= MAX_PRESALE, "Molly: Selected amount exceeds the max presale supply" ); presaleCount += amount; currentSupply += amount; presaleMintLog[ msg.sender ] += amount; mintBatch(msg.sender, currentSupply - amount, amount); } function publicSaleMint(uint256 amount) external payable { require( amount > 0, "You must mint at least one NFT."); uint256 supply = currentSupply; require( supply < maxSupply, "Molly: Sold out!" ); require( supply + amount <= maxSupply, "Molly: Selected amount exceeds the max supply."); require( workflow == WorkflowStatus.Sale, "Molly: Public sale has not active." ); require( msg.value >= salePrice * amount, "Molly: Insuficient ETH amount sent." ); publicMintLog[ msg.sender ] += amount; currentSupply += amount; mintBatch(msg.sender, supply, amount); } function forceMint(uint256 number, address receiver) external onlyOwner { uint256 supply = currentSupply; require( supply + number <= maxSupply, "Molly: You can't mint more than max supply" ); currentSupply += number; mintBatch( receiver, supply, number); } function ownerMint(uint256 number) external onlyOwner { uint256 supply = currentSupply; require( supply + number <= maxSupply, "Molly: You can't mint more than max supply" ); currentSupply += number; mintBatch(msg.sender, supply, number); } function airdrop(address[] calldata addresses) external onlyOwner { uint256 supply = currentSupply; require( supply + addresses.length <= maxSupply, "Molly: You can't mint more than max supply" ); currentSupply += addresses.length; for (uint256 i = 0; i < addresses.length; i++) { _safeMint(addresses[i], supply + i); } } function setUpBefore() external onlyOwner { workflow = WorkflowStatus.Before; } function setUpPresale() external onlyOwner { workflow = WorkflowStatus.Presale; } function setUpSale() external onlyOwner { workflow = WorkflowStatus.Sale; } function pauseSale() external onlyOwner { workflow = WorkflowStatus.Paused; } function setMaxPerWallet( uint256 _amount ) external onlyOwner { maxPerWallet = _amount; } function setMaxFree( uint256 _amount ) external onlyOwner { MAX_FREE = _amount; } function setMaxPresale( uint256 _amount ) external onlyOwner { MAX_PRESALE = _amount; } function openFreeMint() public onlyOwner { freeMintOpened = true; } function stopFreeMint() public onlyOwner { freeMintOpened = false; } function reveal() public onlyOwner { revealed = true; } function setNotRevealedURI(string memory _notRevealedURI) public onlyOwner { notRevealedUri = _notRevealedURI; } function setBaseURI(string memory _newBaseURI) public onlyOwner { require( baseLocked == false, "Base URI change has been disabled permanently"); baseURI = _newBaseURI; } function setPresaleAddress(address _newAddress) public onlyOwner { require(_newAddress != address(0), "CAN'T PUT 0 ADDRESS"); presaleAddress = _newAddress; } function setWallet(address _newWallet) public onlyOwner { wallet = _newWallet; } function setSalePrice(uint256 _newPrice) public onlyOwner { salePrice = _newPrice; } function setPresalePrice(uint256 _newPrice) public onlyOwner { presalePrice = _newPrice; } function setFreeMintAccess(address _acc, uint256 _am ) public onlyOwner { freeMintAccess[ _acc ] = _am; } //Lock base security - your nfts can never be changed. function lockBase() public onlyOwner { baseLocked = true; } //Once opened, it can not be closed again function openMarket() public onlyOwner { marketOpened = true; } // FACTORY function tokenURI(uint256 tokenId) public view override(ERC721) returns (string memory) { if (revealed == false) { return notRevealedUri; } string memory currentBaseURI = baseURI; return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(currentBaseURI, tokenId.toString(),'.json')) : ""; } function initFree() internal { freeMintAccess[ address(0x3fEdc94dB76395a83982277203cB5789ABa955b4) ] = 23; freeMintAccess[ address(0xdFA7ae04064eE82378b01FDe8Fcd1aE72cE957a8) ] = 22; freeMintAccess[ address(0x793089C3170C6968a7ea0cA42b3E58a12C3F7c22) ] = 15; freeMintAccess[ address(0x4c1447148B00692bFd46b9f67A26be44Caa115fA) ] = 13; freeMintAccess[ address(0x27F419ea59873fDed5aa65220792EDB6187b5036) ] = 10; freeMintAccess[ address(0x919D316475DD4B894E2926Fe2c24B329d8Ade524) ] = 10; freeMintAccess[ address(0xE0F6Bb10e17Ae2fEcD114d43603482fcEa5A9654) ] = 10; freeMintAccess[ address(0xC6Ac567b250b986acAE49A842Dad7865dA4be3a0) ] = 10; freeMintAccess[ address(0x4a9b4cea73531Ebbe64922639683574104e72E4E) ] = 8; freeMintAccess[ address(0xE5d08078CA78C9B14101f16fcACbEE8818D06Bfa) ] = 6; freeMintAccess[ address(0x7226a4ce2023D5E1228FA55C325bC6D83686c9B7) ] = 6; freeMintAccess[ address(0x2132F5a587163540E0858c3258A6813d31fde053) ] = 5; freeMintAccess[ address(0xC24838b9077720a30935A73C17d18872E570D7c9) ] = 5; freeMintAccess[ address(0x522dC68b2fd2da341d1d25595101E27118B232bD) ] = 5; freeMintAccess[ address(0x5c8aD9343c76CCE594cB3B663410DD2fa1aC0e78) ] = 5; freeMintAccess[ address(0x2bBD55313F6aFF47638DFe9CbCe59c3428A8C969) ] = 5; freeMintAccess[ address(0xc2Ad53Dcdb5A82ce0ed9F165De1BC614031Ff729) ] = 5; freeMintAccess[ address(0x12C97D5933f2cFCAA64FdfcC45c89705c89Ca8f1) ] = 5; freeMintAccess[ address(0x5b7A238EcE076288D58104AAAB26FA3fbf715957) ] = 5; freeMintAccess[ address(0xE170dE7864c63A2442C6FBf5Fff8322D5c72D4fe) ] = 4; freeMintAccess[ address(0x6EDf6b0229C9A205d0D0E4f81e6a956e064ECFAa) ] = 4; freeMintAccess[ address(0x8813df11Cf5DDc4cFb234eD7Bf78b2CfA9a63Ce5) ] = 4; freeMintAccess[ address(0x0081c79304AB6eB2824BDb5f419193ca6d506111) ] = 4; freeMintAccess[ address(0xFaeFb5433b70f5D0857cc7f65b32eeae0316aBcb) ] = 4; freeMintAccess[ address(0xBaA3f0f0983267D1B9847B6328eDa968Aa5cB0e5) ] = 4; freeMintAccess[ address(0xcC0862A45c1c446E62FB99387cEa44Ef4C4FC2D4) ] = 4; freeMintAccess[ address(0xb2aF4F684f3B660703f0dc0EabfDe9f8FB185C21) ] = 4; freeMintAccess[ address(0xc650846f6D9C7E0EE2A4EaAD6f4Be09789eC7141) ] = 3; freeMintAccess[ address(0xd8777f3f65E84CCdca6a4f2C4dCDC1a11030132c) ] = 3; freeMintAccess[ address(0x8CEe034078EADd552D0c8E6E80e45A9B3A7A5BE9) ] = 3; freeMintAccess[ address(0xc70A3Ad498E0Db94d0752cBF05dC4210aCDa0d1F) ] = 3; freeMintAccess[ address(0xCE5443fE2C6B2542C1331Bed2d82f0dd9c14ebbe) ] = 3; freeMintAccess[ address(0xa8f6deDCAe4D391Eaa009CB6f848bB31fDB47D02) ] = 3; freeMintAccess[ address(0x69e69571d0d07EdBEde6c43849e8d877573eE6bf) ] = 3; freeMintAccess[ address(0x40E5529fc270566dD00272af0Bfa684C230cb210) ] = 3; freeMintAccess[ address(0x15dB6B0c9D7195d7413f165dCc430cA8F520886c) ] = 3; freeMintAccess[ address(0x972f7dB01E68bDa714971a10061B13A563DFF012) ] = 3; freeMintAccess[ address(0x065735841E157d74Cd2D69A95d3E4C4003A76E28) ] = 3; freeMintAccess[ address(0xc9eD33f42bB0Dc26E7bA76BF61820328F03a3e5f) ] = 3; freeMintAccess[ address(0x45896c9885066Fe00D1C9c95B962CD5e6579bAC5) ] = 3; freeMintAccess[ address(0x26b7e7a30E75A468cCcC8940D4C5829910aF5073) ] = 3; freeMintAccess[ address(0x6BFc87A9559F0d2129C9A418821A6F1Be09d1991) ] = 3; freeMintAccess[ address(0x9E75aa8Da215804fa82c8C6b5F24bBb7fF069541) ] = 3; freeMintAccess[ address(0x3CB1FE91005B4B92F59D99D2611A0f3C6Ca1aBbb) ] = 3; freeMintAccess[ address(0xe120f27AC40AA4f755ebD3781C259425Ad1F9434) ] = 3; freeMintAccess[ address(0x400665C0eb68da4564bbbD6A24bBfac65Bd17305) ] = 3; freeMintAccess[ address(0xe4aF5C7037D690267bbee5C770ae5D3A1Da70862) ] = 3; freeMintAccess[ address(0x4CB764d39555228EAA5dCCB4b7E5bcdBfa417b75) ] = 3; freeMintAccess[ address(0xab0281C998BEcD891b0A1Cb443d915Af398Df443) ] = 3; freeMintAccess[ address(0xacCB1e0eAa4d6bB3AB8268cFa8fB08d77F082655) ] = 3; freeMintAccess[ address(0x6571cb1fc92d71238aE992271D4Fca16e950a40A) ] = 2; freeMintAccess[ address(0x05120B86e5ABFEC60a3ba7AbF60D74CF9a7d49e9) ] = 2; freeMintAccess[ address(0xdE694b3D3DDC92914F87c8618B067a6306BAcEDA) ] = 2; freeMintAccess[ address(0xa215495dB3a2923c74BF570F5253e5Bc05247635) ] = 2; freeMintAccess[ address(0x08528a318b20e6213d1b848Baef381B3819c139b) ] = 2; freeMintAccess[ address(0x545152C6c3077579702d60A1764a405575F395B2) ] = 2; freeMintAccess[ address(0x92b449114420c1b3F10324491727De57809f9Cc8) ] = 2; freeMintAccess[ address(0xFc045bFbA2Cc210993DA7D0e5240575Cd4292558) ] = 2; freeMintAccess[ address(0x03D98243C825b799E518e1AA4c9314E6614896b2) ] = 2; freeMintAccess[ address(0xdC8A96B8613C7f4834F1abC5cf52b0c6FC0730A2) ] = 2; freeMintAccess[ address(0xdE3ce6E4bc4967449CD1135a31D5Ae9365E0681d) ] = 2; freeMintAccess[ address(0xcEc32F9df33A482A02B80E9e5b41cb4970Bc4976) ] = 2; freeMintAccess[ address(0x94c1CB2cecb2a0e9BE3A8C24e11507BE5Ebce172) ] = 2; freeMintAccess[ address(0xaC08C1b08430aA3976D6d26E837cd4955e3530aA) ] = 2; freeMintAccess[ address(0x20B7A3C7B517e440ffFdfECf505e91D55484072E) ] = 2; freeMintAccess[ address(0x392623dfDAAF78C78Df19a92880A2f5F21044365) ] = 2; freeMintAccess[ address(0x546630E317b4732870437d9277dd2ed92758805F) ] = 2; freeMintAccess[ address(0x7E7c1A3541d2ff134f755ca58512B703906f2785) ] = 2; freeMintAccess[ address(0xeE4B71C36d17b1c70E438F8204907C5e068229cc) ] = 2; freeMintAccess[ address(0xe1E7A079D5bBFa741f6FA850B9100bAA0B59689C) ] = 2; freeMintAccess[ address(0x3C03Fb9387524111D5528eC19B606eF22D107AC0) ] = 2; freeMintAccess[ address(0x5F4dF796b08AcAb25dc35b14e4D3Fd0b1588290e) ] = 2; freeMintAccess[ address(0xE0f4f6cFb0CD8cE76e99AF76E7018F47E54D414F) ] = 2; freeMintAccess[ address(0x75deF0e0adAF2Cad3Ae505fDaD1fd1BeAFdB0A16) ] = 2; freeMintAccess[ address(0x02098bf554A48707579FcB28182D42947c013cfA) ] = 2; freeMintAccess[ address(0x6C543a1aCa8F972d83e4cD072B5b23Ee49ca77f5) ] = 2; freeMintAccess[ address(0x85C26b9287b0b77E41691E12B208396e95f66D2F) ] = 2; freeMintAccess[ address(0x4a437b6078Cfb41bC599C4379A9D27259F1948dF) ] = 2; freeMintAccess[ address(0xed9A912182745fE101ecb4291D00b802d982Ba0F) ] = 2; freeMintAccess[ address(0x68CfFC26438472733803372b7D7Cff58d352DFf4) ] = 2; freeMintAccess[ address(0xAeA6880Ea9374c3C5c9805F8CD5c21679df5f9ac) ] = 2; freeMintAccess[ address(0x0D57D42C7c784DA53325dA4d4287d39fcd9529de) ] = 2; freeMintAccess[ address(0x80Ed258780a60fe518cBc8173566A9eDC8B6598D) ] = 2; freeMintAccess[ address(0xC9516b1845e1150dc55B5081Dd072B6c215383A9) ] = 2; freeMintAccess[ address(0x8C7EE7fE4871DA8e4C2565B9109dC07a19334b43) ] = 2; freeMintAccess[ address(0xFCCB5fa5Aef5481C02fAAA378e663F6259C900fD) ] = 2; freeMintAccess[ address(0x52d09189264FaaA709F1AED9C457e55c9e4B5D29) ] = 2; freeMintAccess[ address(0xF13Eb1Bc8CD592b3888A67B9EFE73F8Bb41c6142) ] = 2; freeMintAccess[ address(0x059a06f9EE4b7D352C0a11E8f0E0995A65f41388) ] = 2; freeMintAccess[ address(0x9487a68681F8E114787C97079ed3E8135E12bca6) ] = 2; freeMintAccess[ address(0x4dD7957e0499624e65d3fd5B3E217948f2e16d38) ] = 2; freeMintAccess[ address(0x6ABaE536325516db0e8e68BAfB06c84FB0a1068d) ] = 2; freeMintAccess[ address(0x7C922CDC663367ed2ba6E84c074385121AA79291) ] = 2; freeMintAccess[ address(0x827cda8f8A1782040af691B73747AbE2Eeee980b) ] = 2; freeMintAccess[ address(0xa71eEA6cfE9f879b05dB8B776e066069419a83be) ] = 2; freeMintAccess[ address(0x69287Fa2B775481a43196F298F6aacF5B6A890E7) ] = 2; freeMintAccess[ address(0xD13667a9c6990f728610039B8D2a8d4A931308c0) ] = 2; freeMintAccess[ address(0x069805bEFFb3deC781aff8b71dB9357Be7ae418c) ] = 2; freeMintAccess[ address(0xAD17C670D27096E8a637C2D4471e355A83E9a754) ] = 2; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s; uint8 v; assembly { s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) v := add(shr(255, vs), 27) } return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./extensions/IERC721Metadata.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/Strings.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @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. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits a {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol 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); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// 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/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (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 `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (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`, 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 be 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 Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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 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); /** * @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; }
// 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); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"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":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","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":"MAX_FREE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PRESALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","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":[],"name":"baseLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"forceMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"freeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"freeMintAccess","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"freeMintLog","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMintOpened","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_acc","type":"address"}],"name":"getFreeMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_acc","type":"address"}],"name":"getFreeMintLog","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSaleStatus","outputs":[{"internalType":"enum DragonMolly.WorkflowStatus","name":"","type":"uint8"}],"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":[],"name":"lockBase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"marketOpened","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openFreeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"openMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"presaleCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"presaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"presaleMintLog","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presalePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"publicMintLog","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"publicSaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[],"name":"salePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_acc","type":"address"},{"internalType":"uint256","name":"_am","type":"uint256"}],"name":"setFreeMintAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setMaxFree","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setMaxPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setMaxPresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_notRevealedURI","type":"string"}],"name":"setNotRevealedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"setPresaleAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setPresalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setSalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setUpBefore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setUpPresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setUpSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newWallet","type":"address"}],"name":"setWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stopFreeMint","outputs":[],"stateMutability":"nonpayable","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":"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":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"workflow","outputs":[{"internalType":"enum DragonMolly.WorkflowStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6104576007556103e8600855611a0a6009556000600a556005600b5567016345785d8a0000600c55666a94d74f430000600d55601080546001600160a01b03199081167341451d6448082c4bb1ded8f7991b02f60738017a1790915560118054821673aabc53116f0b995bde9d61556ef3492043edbf99179055601280549091167354f22e10bc5a24b42cb22b1cddb545aa448d6f3517905560e0604052603560808181529062004c9560a0398051620000c29160149160209091019062001086565b506015805463ffffffff19169055348015620000dd57600080fd5b50604080518082018252600c81526b447261676f6e204d6f6c6c7960a01b60208083019182528351808501909452600b84526a447261676f6e4d6f6c6c7960a81b908401528151919291620001359160009162001086565b5080516200014b90600190602084019062001086565b50505062000168620001626200019060201b60201c565b62000194565b6200017333620001e6565b6015805460ff60201b191690556200018a6200026c565b620011e4565b3390565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b620001f062000190565b6001600160a01b03166200020362001077565b6001600160a01b031614620002355760405162461bcd60e51b81526004016200022c9062001172565b60405180910390fd5b6001600160a01b0381166200025e5760405162461bcd60e51b81526004016200022c906200112c565b620002698162000194565b50565b6016602081905260177f9f040721e692574deb9d83dd415f2c46e571c58436f466e04041999502214103557f3050fb4a4008960fc3fa880973d299ba4fe8d86688cf5519fcccc5654f25259855600f7f16faea1e0aa91589cab70643700124b4b3fedb6495c0974b4f0e64dfb457d40e55600d7fbbe55d2dfd7261113b2c1a572c50f14a505490b0ee5ad922a0249d53911356a555600a7fb561d55d29fe71ccac3ecbc0dda1196ecec4a98304e5ac9ae28028d942448c9e8190557f9cc81bc00023b230779e9c62d4f4fe963b67151cc805173021c09a3fbe236c1b8190557f8ce1f69fa7f83b56e488d691d4f6565413968996aed4b2f87a7b921767bab7308190557f50f6966f0c5d80f85f38325009ef41c8bef4ce4e0fdcc6f00550fe442f8112775560087fb6f2238f164f3dd13ede46957f5f35a58491aca25aeac82af6595d97c791e8155560067f81a4554162257917b089ba7722b7b99861b478da87285f16629623970b6c2a108190557f7454c21a3cd7d9b6ed017f29128c96b31022d9b2466dcb4db41e893099c585ae5560057f88540eda4371b2244b1d075ce3bd2b685c8a954d70d8aac563c87c0bd8663ab08190557f13caaf2b118bfeabbc8316bf45350799a89b223e4b99a6b768cd9db32b58d8a38190557fa49815e881e69f783a1af2ce6d9ec1682a4ef005bbe2ae968dd1954b32d5718d8190557f4417a3d910feb20b37ffcc520283f0123cea3b5b89bf64019aafa2f17ea90a278190557f6738bb4b7ee0bb2be1ae1e95506ad41be64d8103af5aa6d55ddd09e4cbe01cd28190557f138e263134c7d93675d30f1c623fdef92d002b34b358a31d8672dd8c9ddc9f858190557f6aa1355f314ad7d02739e903a0ef88f4c0c10dcea683a781a3a2e9c2373cc6b88190557f869e775d1fa8fd6ab72fe83b016c0134dace1b757064fe0187579a0f9dd8630f5560047fee48447122377d658c4fae477f58d7b9148375393b173dc7fa589da24d468f478190557f3c6702901c06fa7b805312afd2ea37ba20aa9140e56d2de1a62e20190d05ea258190557f45acc966d8acb6f3f0536dde0a306832437afd7f91e97633858fd58bd1d97b6b8190557fed1364546d012d141ea1207ece69e1d1348bbe343703a6dfe7d2acb4fc89cc238190557fea804083ed6eb81020089fc4ea86fce75abcdeb50c75df1795997c0654dfd3968190557fca24384671f7b0055daacfe109f14fab5cc15de322c6448dd1298547a2ed6c818190557f621621512bef6ad603af40618ec48c97862a43aa5d48f403bc5e321a70468f568190557fe6fc56a1263d11851371c1394b6c2686125e6b69e7ce3ac7a2d581e8835e74215560037fd7720b2baa6176bcb2fb1da9d29023321fdcd7c18a55cd0ef600d6e68ce1ae898190557fad02ca46eee9e350eefde4d9847e56db45c49a2ca9a8617b7d7ddbe650004c1b8190557f31963ed959ed87b48691352394bbd887a949968ca6de9a8e4973d7e8fcde56208190557f3a8d1f06d382ad98ad85895069a895382276db43ea959e2c6054fef0222a3f798190557ffed03bd8b6d2b5ca5b6403fa01467a21df02be6c7c59db22147b3822609233128190557fe5850adb710880549b05bbce7fb4d50919ebdd8664a9537e376cd2cb1cfaae0f8190557f03984eabacf00518c71dc7df3b8eb51e73aef0308604854953f1123f801036e08190557fc69384b2b991ec252a063508a8ef55e6353add48c66e8d0a9607bad5717594248190557fc622b74e319d50d73a6947bcd1a4bc477f8f96db95dad864b2f8d8f9e76efcac8190557f8d9ca6f3e3a2e5a4848239800d6b503aca00393baaf52cfd74a842f18f9021e88190557ff4df9c72546d2570d17def9910eccea288503db620a3e05f2354c0924fba854b8190557f7e33a41eaaf1cbdbe6e8207c9c4da2d4da5add88055bd7f183e59c6788fb88108190557fc3fc91fc18b75e72d2b936802fdc0f88ba956712bf1fe6e43a6e26cdab0d1f368190557f92160debb5af7052110cd8a4d2e46217be1c7e15485307758f8818a636ff9de78190557f5eff4a12169a17a036e1cc22253a991741bf029fbf200833530b62c4b202853d8190557fb22da263228b8c397b6c27abcd6549842aaaccf53af73618ee7a42c7580665648190557f0dc67d541304da6d77d9a11da00954c98b63f4dbe4d905b92540f272fb751ee38190557fd9454317f1f41e12fe2a75f29377d98235932810d3e9a85ea7292b42d761db488190557f6e51c4ba1b5e60846ca1329b17e04f9f76f9192cf30c4572f9b2061197042cea8190557fd7132ec3844e3c4a9ca8ee62c4ce22579c9d28b472c7e7dc97b7225cddff63fc8190557fa278aa8ae3790125b392a6d31bbf50f9b9717af50263d788b39a78bf812d9bda8190557fffecb935edddfebf21193b79e86504b25baf1e41f9b8edfd97c97665a4b2e9958190557fd57bec2be9fc2c5ef13212d721e2be3d79fe636758f23ed4a7374100ade3b8ad5560027f77b263bca00a5a3f720c56f8aefc90817f41354db73f8ff9453467105afd47378190557fc34de29e34f5170b084efde7492b39c643d1a7e8f39a405f7c674de184ea78068190557f9fc5ff551b9408043a8b35c2aadf4420c65a1ea8fb690bb2a7879e52362168ea8190557f9ee41ab4e2b143a0aa921efc5f70aa3b79b2be9c562a7e810eb0d9efdc17cba28190557fcc0c71f4a831a3ca866fc816a9a8ace95269b580bd69ec88f865336ae67f203d8190557fa6b92e1ac8fe4437b505c40ecf843f05dd036b4f7e113d320cad21564395b3df8190557f7e05b32558eaf5890923d3dd64317411a5515d26bae9223d57a5517f7dbc1fc48190557f99ddcb56f2953f2ab6c83777443c5cec0b52d9b8dc0eba37a28e8c4ab049962e8190557faab992ead2245096d07795de13019c163b959cdd9d2535460e954a211a6092b48190557f3df3209b33dec78c20e19c7fbdf7f7880bce2efbef7a4cce19efef5058e235a58190557f64fa60d2d8c54c05c0b7d5df2350e69a977562aacfa46ab558a45926975b892c8190557f2199c93c5a74c073fab9e3e35fdc3c7011d612f4ab742c8e2cced43006280b5a8190557f3f0bad70fdb93d76eedf23552298e7191461d5a8caa0155c803e770d6b457eb78190557fa1c1c4c007d4d175c115b35668475e4cdc1c8de793d32b92fd32304326db7fca8190557fc2dc0bc950f6ca367ec0a2703cdd0f6cb8023b6b66500bb1faa5f02c5f9cfba68190557f55e06e4e573ff63151f336e3b8469fff2e2b41012453ce1054e56d6a569de0888190557facd3d52c8cb8c0c728d9ec484f354a87e00fa811e300a8e71433b2edafb4f9848190557f590ad3255502259d7b2b88c1fe65ac5e2119ee89d1c3dc6b69148e60a71561128190557f3d94118f55086a505f8eb3083b8e2009f16883858494ccdbed34b080e4b25e348190557f196b89f1e92b24bd7caa784c2f020d6db3d03c3127ea3165602c3bd300f178818190557f33b9effa6f8dd660482e82a00f7f23c2d9597aea011c94fd580f506c40b68b888190557f8d7770a6af219e0ed24cc15ccce3c558112ab7c530e752d9c8ac574f345a3f688190557fb0886b6547095edf53941e7eaccca10a24f5691bd72bfd1ef8cf75aecff248618190557f02126ba8f970ff39c2cc1bfe88541f051344f1b74a79bd819edb079f5494bc518190557f862f6e4943e9d7fefc6f654a1805e6ab6263423a7d6bdf50d0df734dba073ba08190557fee5431a2111248663fc22bb306bcdf203efff7448beeedf2dc428cc795c749ed8190557f0c0e49ca78cb543e5022e79ed1f16d347a68bcdd95942b3e003d7ac011b57b208190557fa179d2968e93c60b7ed0310f7e5eb57227e518683e34950a98d4b9c2345a1ecb8190557fbbb21e991553f4086563a663266839df1dd6fc2945ea51a67d049ce1272acf1c8190557f600021e3548cc0988c7f9841a8bde6f9bc7ecccc7ce1acdf10084890128ae83e8190557f32fa3afc993242919e917a3b170150f39e475e5122aec6d3327d40c8977dbe798190557ff2b0d91291ef5a28251c8ab79a771949a0b1e5dc5bcd13d4359f9e061203c25d8190557fd5e2915e2c12711bb6b8607409ea382897fce155160f5ca074c608d377fd642f8190557ff4a529f2907bd8ebda18c81d51462341e79e042ebbe4da28e89f2cd420a8300a8190557f2d7438cd69f84d9e329def0435f15d5831e5aaa8ef85e6651e3d14f1ad26db728190557f49f57e7630eb4014e1ce09914d680180e9ccc6dc8aff85a718abfa86c887a4918190557f1777a9edaf11074dd131fd8c099cff801b5d2465290c308dd1d5842e473f30de8190557f245b4291ccb7e58cd1e4e0911bb88ce0de99b7e75956be65bb2ba2ac033a14be8190557f10a35acf33f316417c50f4e46e550e5db35447ddb825468d7b7208360d09a6928190557f2267e50be874ea8cd0bb240a4f1c7ecd28fed4ed68ab8706693096394355ff8a8190557fcc2d770249d77da80e0508cd0f9a165fad5ec1ba756ebc9f4d252ef5eff724958190557f91b1aaf87c4f8193c45c881c7817b0bd3ceb47bf29afdd19100491180dd8d3998190557f18a148d0e8c73846be5cd0b0635f08c9a6ebf6086ceaa6bfeb89ffab150e2b028190557f125fd68402908456456fc244a63778064e672f8989b57974f4db919e98719c088190557fc43db0267c6d368d158ecb4064470127a06bd68bf368c06a42403cf6d78011a98190557f37b3535c20c06ab528c542751fce12c98ad3dc5a4bab57376ac53b1f8a15fa708190557f19857fdb1f0ce87ae539df024d190ca6a2a4f192bc5bd2cb74d2e5823cb51b038190557f757d52c697c4e1a8552978feed2bb1105419227132ae79777fa685693837113781905573ad17c670d27096e8a637c2d4471e355a83e9a7546000527fbf05c0780ff3feb768ebd94311f2a45b936125af2bd2e6fb921ca9be1633ec1a55565b6006546001600160a01b031690565b8280546200109490620011a7565b90600052602060002090601f016020900481019282620010b8576000855562001103565b82601f10620010d357805160ff191683800117855562001103565b8280016001018555821562001103579182015b8281111562001103578251825591602001919060010190620010e6565b506200111192915062001115565b5090565b5b8082111562001111576000815560010162001116565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600281046001821680620011bc57607f821691505b60208210811415620011de57634e487b7160e01b600052602260045260246000fd5b50919050565b613aa180620011f46000396000f3fe6080604052600436106103c25760003560e01c8063847e2101116101f2578063cde27a351161010d578063e985e9c5116100a0578063f2fde38b1161006f578063f2fde38b14610a47578063f51f96dd14610a67578063fb7ddd0414610a7c578063fd24a85414610a9c576103c2565b8063e985e9c5146109d2578063ed6661c2146109f2578063f19e75d414610a07578063f2c4ce1e14610a27576103c2565b8063d8a4169e116100dc578063d8a4169e1461095d578063deaa59df14610972578063e208b17e14610992578063e268e4d3146109b2576103c2565b8063cde27a35146108fe578063d10a1a2b14610913578063d5abeb0114610928578063d755bf991461093d576103c2565b8063a22cb46511610185578063b88d4fde11610154578063b88d4fde1461087e578063bdb9f28d1461089e578063c87b56dd146108be578063cb04aa1f146108de576103c2565b8063a22cb46514610821578063a334412514610841578063a475b5dd14610856578063b3ab66b01461086b576103c2565b8063916d31ff116101c1578063916d31ff146107b757806395d89b41146107d757806397b9bd08146107ec5780639cbb5b4a1461080c576103c2565b8063847e210114610756578063882567ca1461076b5780638c3c4b34146107805780638da5cb5b146107a2576103c2565b80633ccfd60b116102e25780636352211e11610275578063771282f611610244578063771282f6146106ec5780637b082610146107015780638074be9814610716578063817415c414610736576103c2565b80636352211e1461067757806370a0823114610697578063715018a6146106b7578063729ad39e146106cc576103c2565b80634d4c4e99116102b15780634d4c4e9914610618578063518302271461062d57806355367ba91461064257806355f804b314610657576103c2565b80633ccfd60b146105ae57806342842e0e146105c3578063453c2310146105e35780634c709163146105f8576103c2565b80631919fed71161035a578063215a416311610329578063215a41631461054457806323b872dd146105595780633549345e146105795780633606f5b914610599576103c2565b80631919fed7146104da5780631bbc1afa146104fa5780631c03ceb51461051a5780631f2898c31461052f576103c2565b8063095ea7b311610396578063095ea7b31461046e5780630b2af42e1461049057806315c316fc146104b057806318160ddd146104c5576103c2565b80620e7fa8146103c757806301ffc9a7146103f257806306fdde031461041f578063081812fc14610441575b600080fd5b3480156103d357600080fd5b506103dc610aaf565b6040516103e99190613912565b60405180910390f35b3480156103fe57600080fd5b5061041261040d366004612c87565b610ab5565b6040516103e99190612eca565b34801561042b57600080fd5b50610434610afd565b6040516103e99190612f1b565b34801561044d57600080fd5b5061046161045c366004612d05565b610b8f565b6040516103e99190612e79565b34801561047a57600080fd5b5061048e610489366004612bef565b610bdb565b005b34801561049c57600080fd5b5061048e6104ab366004612bef565b610c9b565b3480156104bc57600080fd5b5061048e610cf6565b3480156104d157600080fd5b506103dc610d53565b3480156104e657600080fd5b5061048e6104f5366004612d05565b610d59565b34801561050657600080fd5b5061048e610515366004612d05565b610d9d565b34801561052657600080fd5b5061048e610de1565b34801561053b57600080fd5b5061048e610e31565b34801561055057600080fd5b5061048e610e8b565b34801561056557600080fd5b5061048e610574366004612b01565b610edf565b34801561058557600080fd5b5061048e610594366004612d05565b610f17565b3480156105a557600080fd5b5061048e610f5b565b3480156105ba57600080fd5b5061048e610fad565b3480156105cf57600080fd5b5061048e6105de366004612b01565b61102a565b3480156105ef57600080fd5b506103dc611045565b34801561060457600080fd5b506103dc610613366004612ab5565b61104b565b34801561062457600080fd5b506103dc61105d565b34801561063957600080fd5b50610412611063565b34801561064e57600080fd5b5061048e61106c565b34801561066357600080fd5b5061048e610672366004612cbf565b6110c6565b34801561068357600080fd5b50610461610692366004612d05565b611140565b3480156106a357600080fd5b506103dc6106b2366004612ab5565b611175565b3480156106c357600080fd5b5061048e6111b9565b3480156106d857600080fd5b5061048e6106e7366004612c18565b611204565b3480156106f857600080fd5b506103dc6112f6565b34801561070d57600080fd5b506104126112fc565b34801561072257600080fd5b5061048e610731366004612d1d565b61130a565b34801561074257600080fd5b5061048e610751366004612d3f565b61139a565b34801561076257600080fd5b5061048e611554565b34801561077757600080fd5b506104126115ae565b34801561078c57600080fd5b506107956115bd565b6040516103e99190612ef3565b3480156107ae57600080fd5b506104616115cd565b3480156107c357600080fd5b506103dc6107d2366004612ab5565b6115dc565b3480156107e357600080fd5b506104346115ee565b3480156107f857600080fd5b506103dc610807366004612ab5565b6115fd565b34801561081857600080fd5b50610412611618565b34801561082d57600080fd5b5061048e61083c366004612bb5565b611628565b34801561084d57600080fd5b50610795611662565b34801561086257600080fd5b5061048e611672565b61048e610879366004612d05565b6116c0565b34801561088a57600080fd5b5061048e610899366004612b3c565b6117f0565b3480156108aa57600080fd5b5061048e6108b9366004612ab5565b611829565b3480156108ca57600080fd5b506104346108d9366004612d05565b6118b0565b3480156108ea57600080fd5b506103dc6108f9366004612ab5565b611a2e565b34801561090a57600080fd5b506103dc611a40565b34801561091f57600080fd5b506103dc611a46565b34801561093457600080fd5b506103dc611a4c565b34801561094957600080fd5b5061048e610958366004612d05565b611a52565b34801561096957600080fd5b5061048e611a96565b34801561097e57600080fd5b5061048e61098d366004612ab5565b611ae4565b34801561099e57600080fd5b506103dc6109ad366004612ab5565b611b45565b3480156109be57600080fd5b5061048e6109cd366004612d05565b611b57565b3480156109de57600080fd5b506104126109ed366004612acf565b611b9b565b3480156109fe57600080fd5b506103dc611bcb565b348015610a1357600080fd5b5061048e610a22366004612d05565b611bd1565b348015610a3357600080fd5b5061048e610a42366004612cbf565b611c50565b348015610a5357600080fd5b5061048e610a62366004612ab5565b611ca2565b348015610a7357600080fd5b506103dc611d13565b348015610a8857600080fd5b506103dc610a97366004612ab5565b611d19565b61048e610aaa366004612d3f565b611d34565b600d5481565b60006001600160e01b031982166380ac58cd60e01b1480610ae657506001600160e01b03198216635b5e139f60e01b145b80610af55750610af582611f0b565b90505b919050565b606060008054610b0c906139a9565b80601f0160208091040260200160405190810160405280929190818152602001828054610b38906139a9565b8015610b855780601f10610b5a57610100808354040283529160200191610b85565b820191906000526020600020905b815481529060010190602001808311610b6857829003601f168201915b5050505050905090565b6000610b9a82611f24565b610bbf5760405162461bcd60e51b8152600401610bb6906135f2565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60155462010000900460ff16610c035760405162461bcd60e51b8152600401610bb690613327565b6000610c0e82611140565b9050806001600160a01b0316836001600160a01b03161415610c425760405162461bcd60e51b8152600401610bb6906136e6565b806001600160a01b0316610c54611f41565b6001600160a01b03161480610c705750610c70816109ed611f41565b610c8c5760405162461bcd60e51b8152600401610bb6906133d2565b610c968383611f45565b505050565b610ca3611f41565b6001600160a01b0316610cb46115cd565b6001600160a01b031614610cda5760405162461bcd60e51b8152600401610bb69061363e565b6001600160a01b03909116600090815260166020526040902055565b610cfe611f41565b6001600160a01b0316610d0f6115cd565b6001600160a01b031614610d355760405162461bcd60e51b8152600401610bb69061363e565b601580546001919064ff000000001916600160201b835b0217905550565b600a5490565b610d61611f41565b6001600160a01b0316610d726115cd565b6001600160a01b031614610d985760405162461bcd60e51b8152600401610bb69061363e565b600c55565b610da5611f41565b6001600160a01b0316610db66115cd565b6001600160a01b031614610ddc5760405162461bcd60e51b8152600401610bb69061363e565b600755565b610de9611f41565b6001600160a01b0316610dfa6115cd565b6001600160a01b031614610e205760405162461bcd60e51b8152600401610bb69061363e565b6015805461ff001916610100179055565b610e39611f41565b6001600160a01b0316610e4a6115cd565b6001600160a01b031614610e705760405162461bcd60e51b8152600401610bb69061363e565b601580546002919064ff000000001916600160201b83610d4c565b610e93611f41565b6001600160a01b0316610ea46115cd565b6001600160a01b031614610eca5760405162461bcd60e51b8152600401610bb69061363e565b6015805463ff00000019166301000000179055565b610ef0610eea611f41565b82611fb3565b610f0c5760405162461bcd60e51b8152600401610bb69061375c565b610c96838383612038565b610f1f611f41565b6001600160a01b0316610f306115cd565b6001600160a01b031614610f565760405162461bcd60e51b8152600401610bb69061363e565b600d55565b610f63611f41565b6001600160a01b0316610f746115cd565b6001600160a01b031614610f9a5760405162461bcd60e51b8152600401610bb69061363e565b6015805462ff0000191662010000179055565b610fb5611f41565b6001600160a01b0316610fc66115cd565b6001600160a01b031614610fec5760405162461bcd60e51b8152600401610bb69061363e565b60125460405147916001600160a01b03169082156108fc029083906000818181858888f19350505050158015611026573d6000803e3d6000fd5b5050565b610c96838383604051806020016040528060008152506117f0565b600b5481565b60196020526000908152604090205481565b60075481565b60155460ff1681565b611074611f41565b6001600160a01b03166110856115cd565b6001600160a01b0316146110ab5760405162461bcd60e51b8152600401610bb69061363e565b601580546003919064ff000000001916600160201b83610d4c565b6110ce611f41565b6001600160a01b03166110df6115cd565b6001600160a01b0316146111055760405162461bcd60e51b8152600401610bb69061363e565b601554610100900460ff161561112d5760405162461bcd60e51b8152600401610bb690612f65565b8051611026906013906020840190612995565b6000818152600260205260408120546001600160a01b031680610af55760405162461bcd60e51b8152600401610bb690613479565b60006001600160a01b03821661119d5760405162461bcd60e51b8152600401610bb69061342f565b506001600160a01b031660009081526003602052604090205490565b6111c1611f41565b6001600160a01b03166111d26115cd565b6001600160a01b0316146111f85760405162461bcd60e51b8152600401610bb69061363e565b6112026000612165565b565b61120c611f41565b6001600160a01b031661121d6115cd565b6001600160a01b0316146112435760405162461bcd60e51b8152600401610bb69061363e565b600a54600954611253838361391b565b11156112715760405162461bcd60e51b8152600401610bb6906138c8565b82829050600a6000828254611286919061391b565b90915550600090505b828110156112f0576112de8484838181106112ba57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906112cf9190612ab5565b6112d9838561391b565b6121b7565b806112e8816139e4565b91505061128f565b50505050565b600a5481565b601554610100900460ff1681565b611312611f41565b6001600160a01b03166113236115cd565b6001600160a01b0316146113495760405162461bcd60e51b8152600401610bb69061363e565b600a54600954611359848361391b565b11156113775760405162461bcd60e51b8152600401610bb6906138c8565b82600a6000828254611389919061391b565b90915550610c9690508282856121d1565b6015546301000000900460ff166113c35760405162461bcd60e51b8152600401610bb690613586565b601154604080516020601f850181900481028201810190925283815261140d926001600160a01b03169185908590819084018382808284376000920191909152506121fc92505050565b6114295760405162461bcd60e51b8152600401610bb69061329b565b600a5433600090815260166020526040902054600190156114565750336000908152601660205260409020545b33600090815260196020526040902054819061147390879061391b565b11156114915760405162461bcd60e51b8152600401610bb690613081565b60095461149e868461391b565b11156114bc5760405162461bcd60e51b8152600401610bb690613384565b60085485600f546114cd919061391b565b11156114eb5760405162461bcd60e51b8152600401610bb6906134c2565b336000908152601960205260408120805487929061150a90849061391b565b9250508190555084600f6000828254611523919061391b565b9250508190555084600a600082825461153c919061391b565b9091555061154d90503383876121d1565b5050505050565b61155c611f41565b6001600160a01b031661156d6115cd565b6001600160a01b0316146115935760405162461bcd60e51b8152600401610bb69061363e565b601580546000919064ff000000001916600160201b83610d4c565b60155462010000900460ff1681565b601554600160201b900460ff1690565b6006546001600160a01b031690565b60166020526000908152604090205481565b606060018054610b0c906139a9565b6001600160a01b031660009081526019602052604090205490565b6015546301000000900460ff1681565b60155462010000900460ff166116505760405162461bcd60e51b8152600401610bb690613327565b61102661165b611f41565b8383612271565b601554600160201b900460ff1681565b61167a611f41565b6001600160a01b031661168b6115cd565b6001600160a01b0316146116b15760405162461bcd60e51b8152600401610bb69061363e565b6015805460ff19166001179055565b600081116116e05760405162461bcd60e51b8152600401610bb6906137ad565b600a5460095481106117045760405162461bcd60e51b8152600401610bb6906136bc565b600954611711838361391b565b111561172f5760405162461bcd60e51b8152600401610bb69061387a565b6002601554600160201b900460ff16600481111561175d57634e487b7160e01b600052602160045260246000fd5b1461177a5760405162461bcd60e51b8152600401610bb690613184565b81600c546117889190613947565b3410156117a75760405162461bcd60e51b8152600401610bb6906137e4565b33600090815260186020526040812080548492906117c690849061391b565b9250508190555081600a60008282546117df919061391b565b9091555061102690503382846121d1565b6118016117fb611f41565b83611fb3565b61181d5760405162461bcd60e51b8152600401610bb69061375c565b6112f084848484612314565b611831611f41565b6001600160a01b03166118426115cd565b6001600160a01b0316146118685760405162461bcd60e51b8152600401610bb69061363e565b6001600160a01b03811661188e5760405162461bcd60e51b8152600401610bb690613517565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b60155460609060ff1661194f57601480546118ca906139a9565b80601f01602080910402602001604051908101604052809291908181526020018280546118f6906139a9565b80156119435780601f1061191857610100808354040283529160200191611943565b820191906000526020600020905b81548152906001019060200180831161192657829003601f168201915b50505050509050610af8565b60006013805461195e906139a9565b80601f016020809104026020016040519081016040528092919081815260200182805461198a906139a9565b80156119d75780601f106119ac576101008083540402835291602001916119d7565b820191906000526020600020905b8154815290600101906020018083116119ba57829003601f168201915b5050505050905060008151116119fc5760405180602001604052806000815250611a27565b80611a0684612347565b604051602001611a17929190612e09565b6040516020818303038152906040525b9392505050565b60176020526000908152604090205481565b600e5481565b600f5481565b60095481565b611a5a611f41565b6001600160a01b0316611a6b6115cd565b6001600160a01b031614611a915760405162461bcd60e51b8152600401610bb69061363e565b600855565b611a9e611f41565b6001600160a01b0316611aaf6115cd565b6001600160a01b031614611ad55760405162461bcd60e51b8152600401610bb69061363e565b6015805463ff00000019169055565b611aec611f41565b6001600160a01b0316611afd6115cd565b6001600160a01b031614611b235760405162461bcd60e51b8152600401610bb69061363e565b601280546001600160a01b0319166001600160a01b0392909216919091179055565b60186020526000908152604090205481565b611b5f611f41565b6001600160a01b0316611b706115cd565b6001600160a01b031614611b965760405162461bcd60e51b8152600401610bb69061363e565b600b55565b6001600160a01b0380831660009081526005602090815260408083209385168352929052205460ff165b92915050565b60085481565b611bd9611f41565b6001600160a01b0316611bea6115cd565b6001600160a01b031614611c105760405162461bcd60e51b8152600401610bb69061363e565b600a54600954611c20838361391b565b1115611c3e5760405162461bcd60e51b8152600401610bb6906138c8565b81600a60008282546117df919061391b565b611c58611f41565b6001600160a01b0316611c696115cd565b6001600160a01b031614611c8f5760405162461bcd60e51b8152600401610bb69061363e565b8051611026906014906020840190612995565b611caa611f41565b6001600160a01b0316611cbb6115cd565b6001600160a01b031614611ce15760405162461bcd60e51b8152600401610bb69061363e565b6001600160a01b038116611d075760405162461bcd60e51b8152600401610bb69061303b565b611d1081612165565b50565b600c5481565b6001600160a01b031660009081526016602052604090205490565b6001601554600160201b900460ff166004811115611d6257634e487b7160e01b600052602160045260246000fd5b14611d7f5760405162461bcd60e51b8152600401610bb690613208565b601054604080516020601f8501819004810282018101909252838152611dc9926001600160a01b03169185908590819084018382808284376000920191909152506121fc92505050565b611de55760405162461bcd60e51b8152600401610bb69061329b565b60008311611e055760405162461bcd60e51b8152600401610bb690613727565b600b5433600090815260176020526040902054611e2390859061391b565b1115611e415760405162461bcd60e51b8152600401610bb690613827565b82600d54611e4f9190613947565b341015611e6e5760405162461bcd60e51b8152600401610bb6906137e4565b60075483600e54611e7f919061391b565b1115611e9d5760405162461bcd60e51b8152600401610bb6906132d2565b82600e6000828254611eaf919061391b565b9250508190555082600a6000828254611ec8919061391b565b90915550503360009081526017602052604081208054859290611eec90849061391b565b92505081905550610c963384600a54611f059190613966565b856121d1565b6001600160e01b031981166301ffc9a760e01b14919050565b6000908152600260205260409020546001600160a01b0316151590565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611f7a82611140565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611fbe82611f24565b611fda5760405162461bcd60e51b8152600401610bb69061324f565b6000611fe583611140565b9050806001600160a01b0316846001600160a01b031614806120205750836001600160a01b031661201584610b8f565b6001600160a01b0316145b8061203057506120308185611b9b565b949350505050565b826001600160a01b031661204b82611140565b6001600160a01b0316146120715760405162461bcd60e51b8152600401610bb690613673565b6001600160a01b0382166120975760405162461bcd60e51b8152600401610bb690613109565b6120a2838383610c96565b6120ad600082611f45565b6001600160a01b03831660009081526003602052604081208054600192906120d6908490613966565b90915550506001600160a01b038216600090815260036020526040812080546001929061210490849061391b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611026828260405180602001604052806000815250612462565b60005b818110156112f0576121ea846112d9838661391b565b806121f4816139e4565b9150506121d4565b6000803033604051602001612212929190612de2565b604051602081830303815290604052805190602001209050600061223f8461223984612495565b906124c5565b9050806001600160a01b0316856001600160a01b0316141561226657600192505050611bc5565b600092505050611bc5565b816001600160a01b0316836001600160a01b031614156122a35760405162461bcd60e51b8152600401610bb69061314d565b6001600160a01b0383811660008181526005602090815260408083209487168084529490915290819020805460ff1916851515179055517f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190612307908590612eca565b60405180910390a3505050565b61231f848484612038565b61232b848484846124e9565b6112f05760405162461bcd60e51b8152600401610bb690612fe9565b60608161236c57506040805180820190915260018152600360fc1b6020820152610af8565b8160005b81156123965780612380816139e4565b915061238f9050600a83613933565b9150612370565b60008167ffffffffffffffff8111156123bf57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156123e9576020820181803683370190505b5090505b8415612030576123fe600183613966565b915061240b600a866139ff565b61241690603061391b565b60f81b81838151811061243957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535061245b600a86613933565b94506123ed565b61246c8383612604565b61247960008484846124e9565b610c965760405162461bcd60e51b8152600401610bb690612fe9565b6000816040516020016124a89190612e48565b604051602081830303815290604052805190602001209050919050565b60008060006124d485856126e3565b915091506124e181612753565b509392505050565b60006124fd846001600160a01b0316612880565b156125f957836001600160a01b031663150b7a02612519611f41565b8786866040518563ffffffff1660e01b815260040161253b9493929190612e8d565b602060405180830381600087803b15801561255557600080fd5b505af1925050508015612585575060408051601f3d908101601f1916820190925261258291810190612ca3565b60015b6125df573d8080156125b3576040519150601f19603f3d011682016040523d82523d6000602084013e6125b8565b606091505b5080516125d75760405162461bcd60e51b8152600401610bb690612fe9565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612030565b506001949350505050565b6001600160a01b03821661262a5760405162461bcd60e51b8152600401610bb6906135bd565b61263381611f24565b156126505760405162461bcd60e51b8152600401610bb6906130d2565b61265c60008383610c96565b6001600160a01b038216600090815260036020526040812080546001929061268590849061391b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60008082516041141561271a5760208301516040840151606085015160001a61270e87828585612886565b9450945050505061274c565b8251604014156127445760208301516040840151612739868383612966565b93509350505061274c565b506000905060025b9250929050565b600081600481111561277557634e487b7160e01b600052602160045260246000fd5b141561278057611d10565b60018160048111156127a257634e487b7160e01b600052602160045260246000fd5b14156127c05760405162461bcd60e51b8152600401610bb690612f2e565b60028160048111156127e257634e487b7160e01b600052602160045260246000fd5b14156128005760405162461bcd60e51b8152600401610bb690612fb2565b600381600481111561282257634e487b7160e01b600052602160045260246000fd5b14156128405760405162461bcd60e51b8152600401610bb6906131c6565b600481600481111561286257634e487b7160e01b600052602160045260246000fd5b1415611d105760405162461bcd60e51b8152600401610bb690613544565b3b151590565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156128bd575060009050600361295d565b8460ff16601b141580156128d557508460ff16601c14155b156128e6575060009050600461295d565b60006001878787876040516000815260200160405260405161290b9493929190612ed5565b6020604051602081039080840390855afa15801561292d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166129565760006001925092505061295d565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b0161298787828885612886565b935093505050935093915050565b8280546129a1906139a9565b90600052602060002090601f0160209004810192826129c35760008555612a09565b82601f106129dc57805160ff1916838001178555612a09565b82800160010185558215612a09579182015b82811115612a095782518255916020019190600101906129ee565b50612a15929150612a19565b5090565b5b80821115612a155760008155600101612a1a565b600067ffffffffffffffff80841115612a4957612a49613a3f565b604051601f8501601f191681016020018281118282101715612a6d57612a6d613a3f565b604052848152915081838501861015612a8557600080fd5b8484602083013760006020868301015250509392505050565b80356001600160a01b0381168114610af857600080fd5b600060208284031215612ac6578081fd5b611a2782612a9e565b60008060408385031215612ae1578081fd5b612aea83612a9e565b9150612af860208401612a9e565b90509250929050565b600080600060608486031215612b15578081fd5b612b1e84612a9e565b9250612b2c60208501612a9e565b9150604084013590509250925092565b60008060008060808587031215612b51578081fd5b612b5a85612a9e565b9350612b6860208601612a9e565b925060408501359150606085013567ffffffffffffffff811115612b8a578182fd5b8501601f81018713612b9a578182fd5b612ba987823560208401612a2e565b91505092959194509250565b60008060408385031215612bc7578182fd5b612bd083612a9e565b915060208301358015158114612be4578182fd5b809150509250929050565b60008060408385031215612c01578182fd5b612c0a83612a9e565b946020939093013593505050565b60008060208385031215612c2a578182fd5b823567ffffffffffffffff80821115612c41578384fd5b818501915085601f830112612c54578384fd5b813581811115612c62578485fd5b8660208083028501011115612c75578485fd5b60209290920196919550909350505050565b600060208284031215612c98578081fd5b8135611a2781613a55565b600060208284031215612cb4578081fd5b8151611a2781613a55565b600060208284031215612cd0578081fd5b813567ffffffffffffffff811115612ce6578182fd5b8201601f81018413612cf6578182fd5b61203084823560208401612a2e565b600060208284031215612d16578081fd5b5035919050565b60008060408385031215612d2f578182fd5b82359150612af860208401612a9e565b600080600060408486031215612d53578283fd5b83359250602084013567ffffffffffffffff80821115612d71578384fd5b818601915086601f830112612d84578384fd5b813581811115612d92578485fd5b876020828501011115612da3578485fd5b6020830194508093505050509250925092565b60008151808452612dce81602086016020860161397d565b601f01601f19169290920160200192915050565b6bffffffffffffffffffffffff19606093841b811682529190921b16601482015260280190565b60008351612e1b81846020880161397d565b835190830190612e2f81836020880161397d565b64173539b7b760d91b9101908152600501949350505050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612ec090830184612db6565b9695505050505050565b901515815260200190565b93845260ff9290921660208401526040830152606082015260800190565b6020810160058310612f1557634e487b7160e01b600052602160045260246000fd5b91905290565b600060208252611a276020830184612db6565b60208082526018908201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604082015260600190565b6020808252602d908201527f4261736520555249206368616e676520686173206265656e2064697361626c6560408201526c64207065726d616e656e746c7960981b606082015260800190565b6020808252601f908201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526031908201527f596f7520646f6e742068617665207065726d6973696f6e20746f20667265652060408201527036b4b73a103a3430ba1030b6b7bab73a1760791b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b60208082526022908201527f4d6f6c6c793a205075626c69632073616c6520686173206e6f74206163746976604082015261329760f11b606082015260800190565b60208082526022908201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604082015261756560f01b606082015260800190565b60208082526027908201527f4d6f6c6c793a2050726573616c65206973206e6f742063757272656e746c792060408201526630b1ba34bb329760c91b606082015260800190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252601b908201527f5349474e41545552455f56414c49444154494f4e5f4641494c45440000000000604082015260600190565b60208082526035908201527f4d6f6c6c793a2053656c656374656420616d6f756e74206578636565647320746040820152746865206d61782070726573616c6520737570706c7960581b606082015260800190565b6020808252603d908201527f5468652073616c65206f66204e465473206f6e20746865206d61726b6574706c60408201527f6163657320686173206e6f74206265656e206f70656e6564207965742e000000606082015260800190565b6020808252602e908201527f4d6f6c6c793a204d696e7420746f6f206c617267652c20657863656564696e6760408201526d20746865206d6178537570706c7960901b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b60208082526035908201527f4d6f6c6c793a204d696e7420746f6f206c617267652c20657863656564696e67604082015274081d1a1948199c9959481b5a5b9d08185b5bdd5b9d605a1b606082015260800190565b60208082526013908201527243414e2754205055542030204144445245535360681b604082015260600190565b60208082526022908201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604082015261756560f01b606082015260800190565b6020808252601c908201527f46726565206d696e74206973206e6f74206f70656e6564207965742e00000000604082015260600190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b60208082526010908201526f4d6f6c6c793a20536f6c64206f75742160801b604082015260600190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b6020808252818101527f596f75206d757374206d696e74206174206c65617374206f6e6520746f6b656e604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601f908201527f596f75206d757374206d696e74206174206c65617374206f6e65204e46542e00604082015260600190565b60208082526023908201527f4d6f6c6c793a20496e737566696369656e742045544820616d6f756e74207365604082015262373a1760e91b606082015260800190565b60208082526033908201527f4d6f6c6c793a20596f75206861766520657863656564656420746865206d6178604082015272207065722077616c6c657420616d6f756e742160681b606082015260800190565b6020808252602e908201527f4d6f6c6c793a2053656c656374656420616d6f756e742065786365656473207460408201526d34329036b0bc1039bab838363c9760911b606082015260800190565b6020808252602a908201527f4d6f6c6c793a20596f752063616e2774206d696e74206d6f7265207468616e206040820152696d617820737570706c7960b01b606082015260800190565b90815260200190565b6000821982111561392e5761392e613a13565b500190565b60008261394257613942613a29565b500490565b600081600019048311821515161561396157613961613a13565b500290565b60008282101561397857613978613a13565b500390565b60005b83811015613998578181015183820152602001613980565b838111156112f05750506000910152565b6002810460018216806139bd57607f821691505b602082108114156139de57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156139f8576139f8613a13565b5060010190565b600082613a0e57613a0e613a29565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114611d1057600080fdfea26469706673582212207cb07e47c04c51032920ca4d18dffaacdd3c09207e17399407f1a3f663e482f064736f6c63430008000033697066733a2f2f516d636d7971596342756255704b324e6a5876344b315744664465664256503237696b51394b4535553951743442
Deployed Bytecode
0x6080604052600436106103c25760003560e01c8063847e2101116101f2578063cde27a351161010d578063e985e9c5116100a0578063f2fde38b1161006f578063f2fde38b14610a47578063f51f96dd14610a67578063fb7ddd0414610a7c578063fd24a85414610a9c576103c2565b8063e985e9c5146109d2578063ed6661c2146109f2578063f19e75d414610a07578063f2c4ce1e14610a27576103c2565b8063d8a4169e116100dc578063d8a4169e1461095d578063deaa59df14610972578063e208b17e14610992578063e268e4d3146109b2576103c2565b8063cde27a35146108fe578063d10a1a2b14610913578063d5abeb0114610928578063d755bf991461093d576103c2565b8063a22cb46511610185578063b88d4fde11610154578063b88d4fde1461087e578063bdb9f28d1461089e578063c87b56dd146108be578063cb04aa1f146108de576103c2565b8063a22cb46514610821578063a334412514610841578063a475b5dd14610856578063b3ab66b01461086b576103c2565b8063916d31ff116101c1578063916d31ff146107b757806395d89b41146107d757806397b9bd08146107ec5780639cbb5b4a1461080c576103c2565b8063847e210114610756578063882567ca1461076b5780638c3c4b34146107805780638da5cb5b146107a2576103c2565b80633ccfd60b116102e25780636352211e11610275578063771282f611610244578063771282f6146106ec5780637b082610146107015780638074be9814610716578063817415c414610736576103c2565b80636352211e1461067757806370a0823114610697578063715018a6146106b7578063729ad39e146106cc576103c2565b80634d4c4e99116102b15780634d4c4e9914610618578063518302271461062d57806355367ba91461064257806355f804b314610657576103c2565b80633ccfd60b146105ae57806342842e0e146105c3578063453c2310146105e35780634c709163146105f8576103c2565b80631919fed71161035a578063215a416311610329578063215a41631461054457806323b872dd146105595780633549345e146105795780633606f5b914610599576103c2565b80631919fed7146104da5780631bbc1afa146104fa5780631c03ceb51461051a5780631f2898c31461052f576103c2565b8063095ea7b311610396578063095ea7b31461046e5780630b2af42e1461049057806315c316fc146104b057806318160ddd146104c5576103c2565b80620e7fa8146103c757806301ffc9a7146103f257806306fdde031461041f578063081812fc14610441575b600080fd5b3480156103d357600080fd5b506103dc610aaf565b6040516103e99190613912565b60405180910390f35b3480156103fe57600080fd5b5061041261040d366004612c87565b610ab5565b6040516103e99190612eca565b34801561042b57600080fd5b50610434610afd565b6040516103e99190612f1b565b34801561044d57600080fd5b5061046161045c366004612d05565b610b8f565b6040516103e99190612e79565b34801561047a57600080fd5b5061048e610489366004612bef565b610bdb565b005b34801561049c57600080fd5b5061048e6104ab366004612bef565b610c9b565b3480156104bc57600080fd5b5061048e610cf6565b3480156104d157600080fd5b506103dc610d53565b3480156104e657600080fd5b5061048e6104f5366004612d05565b610d59565b34801561050657600080fd5b5061048e610515366004612d05565b610d9d565b34801561052657600080fd5b5061048e610de1565b34801561053b57600080fd5b5061048e610e31565b34801561055057600080fd5b5061048e610e8b565b34801561056557600080fd5b5061048e610574366004612b01565b610edf565b34801561058557600080fd5b5061048e610594366004612d05565b610f17565b3480156105a557600080fd5b5061048e610f5b565b3480156105ba57600080fd5b5061048e610fad565b3480156105cf57600080fd5b5061048e6105de366004612b01565b61102a565b3480156105ef57600080fd5b506103dc611045565b34801561060457600080fd5b506103dc610613366004612ab5565b61104b565b34801561062457600080fd5b506103dc61105d565b34801561063957600080fd5b50610412611063565b34801561064e57600080fd5b5061048e61106c565b34801561066357600080fd5b5061048e610672366004612cbf565b6110c6565b34801561068357600080fd5b50610461610692366004612d05565b611140565b3480156106a357600080fd5b506103dc6106b2366004612ab5565b611175565b3480156106c357600080fd5b5061048e6111b9565b3480156106d857600080fd5b5061048e6106e7366004612c18565b611204565b3480156106f857600080fd5b506103dc6112f6565b34801561070d57600080fd5b506104126112fc565b34801561072257600080fd5b5061048e610731366004612d1d565b61130a565b34801561074257600080fd5b5061048e610751366004612d3f565b61139a565b34801561076257600080fd5b5061048e611554565b34801561077757600080fd5b506104126115ae565b34801561078c57600080fd5b506107956115bd565b6040516103e99190612ef3565b3480156107ae57600080fd5b506104616115cd565b3480156107c357600080fd5b506103dc6107d2366004612ab5565b6115dc565b3480156107e357600080fd5b506104346115ee565b3480156107f857600080fd5b506103dc610807366004612ab5565b6115fd565b34801561081857600080fd5b50610412611618565b34801561082d57600080fd5b5061048e61083c366004612bb5565b611628565b34801561084d57600080fd5b50610795611662565b34801561086257600080fd5b5061048e611672565b61048e610879366004612d05565b6116c0565b34801561088a57600080fd5b5061048e610899366004612b3c565b6117f0565b3480156108aa57600080fd5b5061048e6108b9366004612ab5565b611829565b3480156108ca57600080fd5b506104346108d9366004612d05565b6118b0565b3480156108ea57600080fd5b506103dc6108f9366004612ab5565b611a2e565b34801561090a57600080fd5b506103dc611a40565b34801561091f57600080fd5b506103dc611a46565b34801561093457600080fd5b506103dc611a4c565b34801561094957600080fd5b5061048e610958366004612d05565b611a52565b34801561096957600080fd5b5061048e611a96565b34801561097e57600080fd5b5061048e61098d366004612ab5565b611ae4565b34801561099e57600080fd5b506103dc6109ad366004612ab5565b611b45565b3480156109be57600080fd5b5061048e6109cd366004612d05565b611b57565b3480156109de57600080fd5b506104126109ed366004612acf565b611b9b565b3480156109fe57600080fd5b506103dc611bcb565b348015610a1357600080fd5b5061048e610a22366004612d05565b611bd1565b348015610a3357600080fd5b5061048e610a42366004612cbf565b611c50565b348015610a5357600080fd5b5061048e610a62366004612ab5565b611ca2565b348015610a7357600080fd5b506103dc611d13565b348015610a8857600080fd5b506103dc610a97366004612ab5565b611d19565b61048e610aaa366004612d3f565b611d34565b600d5481565b60006001600160e01b031982166380ac58cd60e01b1480610ae657506001600160e01b03198216635b5e139f60e01b145b80610af55750610af582611f0b565b90505b919050565b606060008054610b0c906139a9565b80601f0160208091040260200160405190810160405280929190818152602001828054610b38906139a9565b8015610b855780601f10610b5a57610100808354040283529160200191610b85565b820191906000526020600020905b815481529060010190602001808311610b6857829003601f168201915b5050505050905090565b6000610b9a82611f24565b610bbf5760405162461bcd60e51b8152600401610bb6906135f2565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60155462010000900460ff16610c035760405162461bcd60e51b8152600401610bb690613327565b6000610c0e82611140565b9050806001600160a01b0316836001600160a01b03161415610c425760405162461bcd60e51b8152600401610bb6906136e6565b806001600160a01b0316610c54611f41565b6001600160a01b03161480610c705750610c70816109ed611f41565b610c8c5760405162461bcd60e51b8152600401610bb6906133d2565b610c968383611f45565b505050565b610ca3611f41565b6001600160a01b0316610cb46115cd565b6001600160a01b031614610cda5760405162461bcd60e51b8152600401610bb69061363e565b6001600160a01b03909116600090815260166020526040902055565b610cfe611f41565b6001600160a01b0316610d0f6115cd565b6001600160a01b031614610d355760405162461bcd60e51b8152600401610bb69061363e565b601580546001919064ff000000001916600160201b835b0217905550565b600a5490565b610d61611f41565b6001600160a01b0316610d726115cd565b6001600160a01b031614610d985760405162461bcd60e51b8152600401610bb69061363e565b600c55565b610da5611f41565b6001600160a01b0316610db66115cd565b6001600160a01b031614610ddc5760405162461bcd60e51b8152600401610bb69061363e565b600755565b610de9611f41565b6001600160a01b0316610dfa6115cd565b6001600160a01b031614610e205760405162461bcd60e51b8152600401610bb69061363e565b6015805461ff001916610100179055565b610e39611f41565b6001600160a01b0316610e4a6115cd565b6001600160a01b031614610e705760405162461bcd60e51b8152600401610bb69061363e565b601580546002919064ff000000001916600160201b83610d4c565b610e93611f41565b6001600160a01b0316610ea46115cd565b6001600160a01b031614610eca5760405162461bcd60e51b8152600401610bb69061363e565b6015805463ff00000019166301000000179055565b610ef0610eea611f41565b82611fb3565b610f0c5760405162461bcd60e51b8152600401610bb69061375c565b610c96838383612038565b610f1f611f41565b6001600160a01b0316610f306115cd565b6001600160a01b031614610f565760405162461bcd60e51b8152600401610bb69061363e565b600d55565b610f63611f41565b6001600160a01b0316610f746115cd565b6001600160a01b031614610f9a5760405162461bcd60e51b8152600401610bb69061363e565b6015805462ff0000191662010000179055565b610fb5611f41565b6001600160a01b0316610fc66115cd565b6001600160a01b031614610fec5760405162461bcd60e51b8152600401610bb69061363e565b60125460405147916001600160a01b03169082156108fc029083906000818181858888f19350505050158015611026573d6000803e3d6000fd5b5050565b610c96838383604051806020016040528060008152506117f0565b600b5481565b60196020526000908152604090205481565b60075481565b60155460ff1681565b611074611f41565b6001600160a01b03166110856115cd565b6001600160a01b0316146110ab5760405162461bcd60e51b8152600401610bb69061363e565b601580546003919064ff000000001916600160201b83610d4c565b6110ce611f41565b6001600160a01b03166110df6115cd565b6001600160a01b0316146111055760405162461bcd60e51b8152600401610bb69061363e565b601554610100900460ff161561112d5760405162461bcd60e51b8152600401610bb690612f65565b8051611026906013906020840190612995565b6000818152600260205260408120546001600160a01b031680610af55760405162461bcd60e51b8152600401610bb690613479565b60006001600160a01b03821661119d5760405162461bcd60e51b8152600401610bb69061342f565b506001600160a01b031660009081526003602052604090205490565b6111c1611f41565b6001600160a01b03166111d26115cd565b6001600160a01b0316146111f85760405162461bcd60e51b8152600401610bb69061363e565b6112026000612165565b565b61120c611f41565b6001600160a01b031661121d6115cd565b6001600160a01b0316146112435760405162461bcd60e51b8152600401610bb69061363e565b600a54600954611253838361391b565b11156112715760405162461bcd60e51b8152600401610bb6906138c8565b82829050600a6000828254611286919061391b565b90915550600090505b828110156112f0576112de8484838181106112ba57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906112cf9190612ab5565b6112d9838561391b565b6121b7565b806112e8816139e4565b91505061128f565b50505050565b600a5481565b601554610100900460ff1681565b611312611f41565b6001600160a01b03166113236115cd565b6001600160a01b0316146113495760405162461bcd60e51b8152600401610bb69061363e565b600a54600954611359848361391b565b11156113775760405162461bcd60e51b8152600401610bb6906138c8565b82600a6000828254611389919061391b565b90915550610c9690508282856121d1565b6015546301000000900460ff166113c35760405162461bcd60e51b8152600401610bb690613586565b601154604080516020601f850181900481028201810190925283815261140d926001600160a01b03169185908590819084018382808284376000920191909152506121fc92505050565b6114295760405162461bcd60e51b8152600401610bb69061329b565b600a5433600090815260166020526040902054600190156114565750336000908152601660205260409020545b33600090815260196020526040902054819061147390879061391b565b11156114915760405162461bcd60e51b8152600401610bb690613081565b60095461149e868461391b565b11156114bc5760405162461bcd60e51b8152600401610bb690613384565b60085485600f546114cd919061391b565b11156114eb5760405162461bcd60e51b8152600401610bb6906134c2565b336000908152601960205260408120805487929061150a90849061391b565b9250508190555084600f6000828254611523919061391b565b9250508190555084600a600082825461153c919061391b565b9091555061154d90503383876121d1565b5050505050565b61155c611f41565b6001600160a01b031661156d6115cd565b6001600160a01b0316146115935760405162461bcd60e51b8152600401610bb69061363e565b601580546000919064ff000000001916600160201b83610d4c565b60155462010000900460ff1681565b601554600160201b900460ff1690565b6006546001600160a01b031690565b60166020526000908152604090205481565b606060018054610b0c906139a9565b6001600160a01b031660009081526019602052604090205490565b6015546301000000900460ff1681565b60155462010000900460ff166116505760405162461bcd60e51b8152600401610bb690613327565b61102661165b611f41565b8383612271565b601554600160201b900460ff1681565b61167a611f41565b6001600160a01b031661168b6115cd565b6001600160a01b0316146116b15760405162461bcd60e51b8152600401610bb69061363e565b6015805460ff19166001179055565b600081116116e05760405162461bcd60e51b8152600401610bb6906137ad565b600a5460095481106117045760405162461bcd60e51b8152600401610bb6906136bc565b600954611711838361391b565b111561172f5760405162461bcd60e51b8152600401610bb69061387a565b6002601554600160201b900460ff16600481111561175d57634e487b7160e01b600052602160045260246000fd5b1461177a5760405162461bcd60e51b8152600401610bb690613184565b81600c546117889190613947565b3410156117a75760405162461bcd60e51b8152600401610bb6906137e4565b33600090815260186020526040812080548492906117c690849061391b565b9250508190555081600a60008282546117df919061391b565b9091555061102690503382846121d1565b6118016117fb611f41565b83611fb3565b61181d5760405162461bcd60e51b8152600401610bb69061375c565b6112f084848484612314565b611831611f41565b6001600160a01b03166118426115cd565b6001600160a01b0316146118685760405162461bcd60e51b8152600401610bb69061363e565b6001600160a01b03811661188e5760405162461bcd60e51b8152600401610bb690613517565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b60155460609060ff1661194f57601480546118ca906139a9565b80601f01602080910402602001604051908101604052809291908181526020018280546118f6906139a9565b80156119435780601f1061191857610100808354040283529160200191611943565b820191906000526020600020905b81548152906001019060200180831161192657829003601f168201915b50505050509050610af8565b60006013805461195e906139a9565b80601f016020809104026020016040519081016040528092919081815260200182805461198a906139a9565b80156119d75780601f106119ac576101008083540402835291602001916119d7565b820191906000526020600020905b8154815290600101906020018083116119ba57829003601f168201915b5050505050905060008151116119fc5760405180602001604052806000815250611a27565b80611a0684612347565b604051602001611a17929190612e09565b6040516020818303038152906040525b9392505050565b60176020526000908152604090205481565b600e5481565b600f5481565b60095481565b611a5a611f41565b6001600160a01b0316611a6b6115cd565b6001600160a01b031614611a915760405162461bcd60e51b8152600401610bb69061363e565b600855565b611a9e611f41565b6001600160a01b0316611aaf6115cd565b6001600160a01b031614611ad55760405162461bcd60e51b8152600401610bb69061363e565b6015805463ff00000019169055565b611aec611f41565b6001600160a01b0316611afd6115cd565b6001600160a01b031614611b235760405162461bcd60e51b8152600401610bb69061363e565b601280546001600160a01b0319166001600160a01b0392909216919091179055565b60186020526000908152604090205481565b611b5f611f41565b6001600160a01b0316611b706115cd565b6001600160a01b031614611b965760405162461bcd60e51b8152600401610bb69061363e565b600b55565b6001600160a01b0380831660009081526005602090815260408083209385168352929052205460ff165b92915050565b60085481565b611bd9611f41565b6001600160a01b0316611bea6115cd565b6001600160a01b031614611c105760405162461bcd60e51b8152600401610bb69061363e565b600a54600954611c20838361391b565b1115611c3e5760405162461bcd60e51b8152600401610bb6906138c8565b81600a60008282546117df919061391b565b611c58611f41565b6001600160a01b0316611c696115cd565b6001600160a01b031614611c8f5760405162461bcd60e51b8152600401610bb69061363e565b8051611026906014906020840190612995565b611caa611f41565b6001600160a01b0316611cbb6115cd565b6001600160a01b031614611ce15760405162461bcd60e51b8152600401610bb69061363e565b6001600160a01b038116611d075760405162461bcd60e51b8152600401610bb69061303b565b611d1081612165565b50565b600c5481565b6001600160a01b031660009081526016602052604090205490565b6001601554600160201b900460ff166004811115611d6257634e487b7160e01b600052602160045260246000fd5b14611d7f5760405162461bcd60e51b8152600401610bb690613208565b601054604080516020601f8501819004810282018101909252838152611dc9926001600160a01b03169185908590819084018382808284376000920191909152506121fc92505050565b611de55760405162461bcd60e51b8152600401610bb69061329b565b60008311611e055760405162461bcd60e51b8152600401610bb690613727565b600b5433600090815260176020526040902054611e2390859061391b565b1115611e415760405162461bcd60e51b8152600401610bb690613827565b82600d54611e4f9190613947565b341015611e6e5760405162461bcd60e51b8152600401610bb6906137e4565b60075483600e54611e7f919061391b565b1115611e9d5760405162461bcd60e51b8152600401610bb6906132d2565b82600e6000828254611eaf919061391b565b9250508190555082600a6000828254611ec8919061391b565b90915550503360009081526017602052604081208054859290611eec90849061391b565b92505081905550610c963384600a54611f059190613966565b856121d1565b6001600160e01b031981166301ffc9a760e01b14919050565b6000908152600260205260409020546001600160a01b0316151590565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611f7a82611140565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611fbe82611f24565b611fda5760405162461bcd60e51b8152600401610bb69061324f565b6000611fe583611140565b9050806001600160a01b0316846001600160a01b031614806120205750836001600160a01b031661201584610b8f565b6001600160a01b0316145b8061203057506120308185611b9b565b949350505050565b826001600160a01b031661204b82611140565b6001600160a01b0316146120715760405162461bcd60e51b8152600401610bb690613673565b6001600160a01b0382166120975760405162461bcd60e51b8152600401610bb690613109565b6120a2838383610c96565b6120ad600082611f45565b6001600160a01b03831660009081526003602052604081208054600192906120d6908490613966565b90915550506001600160a01b038216600090815260036020526040812080546001929061210490849061391b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611026828260405180602001604052806000815250612462565b60005b818110156112f0576121ea846112d9838661391b565b806121f4816139e4565b9150506121d4565b6000803033604051602001612212929190612de2565b604051602081830303815290604052805190602001209050600061223f8461223984612495565b906124c5565b9050806001600160a01b0316856001600160a01b0316141561226657600192505050611bc5565b600092505050611bc5565b816001600160a01b0316836001600160a01b031614156122a35760405162461bcd60e51b8152600401610bb69061314d565b6001600160a01b0383811660008181526005602090815260408083209487168084529490915290819020805460ff1916851515179055517f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190612307908590612eca565b60405180910390a3505050565b61231f848484612038565b61232b848484846124e9565b6112f05760405162461bcd60e51b8152600401610bb690612fe9565b60608161236c57506040805180820190915260018152600360fc1b6020820152610af8565b8160005b81156123965780612380816139e4565b915061238f9050600a83613933565b9150612370565b60008167ffffffffffffffff8111156123bf57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156123e9576020820181803683370190505b5090505b8415612030576123fe600183613966565b915061240b600a866139ff565b61241690603061391b565b60f81b81838151811061243957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535061245b600a86613933565b94506123ed565b61246c8383612604565b61247960008484846124e9565b610c965760405162461bcd60e51b8152600401610bb690612fe9565b6000816040516020016124a89190612e48565b604051602081830303815290604052805190602001209050919050565b60008060006124d485856126e3565b915091506124e181612753565b509392505050565b60006124fd846001600160a01b0316612880565b156125f957836001600160a01b031663150b7a02612519611f41565b8786866040518563ffffffff1660e01b815260040161253b9493929190612e8d565b602060405180830381600087803b15801561255557600080fd5b505af1925050508015612585575060408051601f3d908101601f1916820190925261258291810190612ca3565b60015b6125df573d8080156125b3576040519150601f19603f3d011682016040523d82523d6000602084013e6125b8565b606091505b5080516125d75760405162461bcd60e51b8152600401610bb690612fe9565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612030565b506001949350505050565b6001600160a01b03821661262a5760405162461bcd60e51b8152600401610bb6906135bd565b61263381611f24565b156126505760405162461bcd60e51b8152600401610bb6906130d2565b61265c60008383610c96565b6001600160a01b038216600090815260036020526040812080546001929061268590849061391b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60008082516041141561271a5760208301516040840151606085015160001a61270e87828585612886565b9450945050505061274c565b8251604014156127445760208301516040840151612739868383612966565b93509350505061274c565b506000905060025b9250929050565b600081600481111561277557634e487b7160e01b600052602160045260246000fd5b141561278057611d10565b60018160048111156127a257634e487b7160e01b600052602160045260246000fd5b14156127c05760405162461bcd60e51b8152600401610bb690612f2e565b60028160048111156127e257634e487b7160e01b600052602160045260246000fd5b14156128005760405162461bcd60e51b8152600401610bb690612fb2565b600381600481111561282257634e487b7160e01b600052602160045260246000fd5b14156128405760405162461bcd60e51b8152600401610bb6906131c6565b600481600481111561286257634e487b7160e01b600052602160045260246000fd5b1415611d105760405162461bcd60e51b8152600401610bb690613544565b3b151590565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156128bd575060009050600361295d565b8460ff16601b141580156128d557508460ff16601c14155b156128e6575060009050600461295d565b60006001878787876040516000815260200160405260405161290b9493929190612ed5565b6020604051602081039080840390855afa15801561292d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166129565760006001925092505061295d565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b0161298787828885612886565b935093505050935093915050565b8280546129a1906139a9565b90600052602060002090601f0160209004810192826129c35760008555612a09565b82601f106129dc57805160ff1916838001178555612a09565b82800160010185558215612a09579182015b82811115612a095782518255916020019190600101906129ee565b50612a15929150612a19565b5090565b5b80821115612a155760008155600101612a1a565b600067ffffffffffffffff80841115612a4957612a49613a3f565b604051601f8501601f191681016020018281118282101715612a6d57612a6d613a3f565b604052848152915081838501861015612a8557600080fd5b8484602083013760006020868301015250509392505050565b80356001600160a01b0381168114610af857600080fd5b600060208284031215612ac6578081fd5b611a2782612a9e565b60008060408385031215612ae1578081fd5b612aea83612a9e565b9150612af860208401612a9e565b90509250929050565b600080600060608486031215612b15578081fd5b612b1e84612a9e565b9250612b2c60208501612a9e565b9150604084013590509250925092565b60008060008060808587031215612b51578081fd5b612b5a85612a9e565b9350612b6860208601612a9e565b925060408501359150606085013567ffffffffffffffff811115612b8a578182fd5b8501601f81018713612b9a578182fd5b612ba987823560208401612a2e565b91505092959194509250565b60008060408385031215612bc7578182fd5b612bd083612a9e565b915060208301358015158114612be4578182fd5b809150509250929050565b60008060408385031215612c01578182fd5b612c0a83612a9e565b946020939093013593505050565b60008060208385031215612c2a578182fd5b823567ffffffffffffffff80821115612c41578384fd5b818501915085601f830112612c54578384fd5b813581811115612c62578485fd5b8660208083028501011115612c75578485fd5b60209290920196919550909350505050565b600060208284031215612c98578081fd5b8135611a2781613a55565b600060208284031215612cb4578081fd5b8151611a2781613a55565b600060208284031215612cd0578081fd5b813567ffffffffffffffff811115612ce6578182fd5b8201601f81018413612cf6578182fd5b61203084823560208401612a2e565b600060208284031215612d16578081fd5b5035919050565b60008060408385031215612d2f578182fd5b82359150612af860208401612a9e565b600080600060408486031215612d53578283fd5b83359250602084013567ffffffffffffffff80821115612d71578384fd5b818601915086601f830112612d84578384fd5b813581811115612d92578485fd5b876020828501011115612da3578485fd5b6020830194508093505050509250925092565b60008151808452612dce81602086016020860161397d565b601f01601f19169290920160200192915050565b6bffffffffffffffffffffffff19606093841b811682529190921b16601482015260280190565b60008351612e1b81846020880161397d565b835190830190612e2f81836020880161397d565b64173539b7b760d91b9101908152600501949350505050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612ec090830184612db6565b9695505050505050565b901515815260200190565b93845260ff9290921660208401526040830152606082015260800190565b6020810160058310612f1557634e487b7160e01b600052602160045260246000fd5b91905290565b600060208252611a276020830184612db6565b60208082526018908201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604082015260600190565b6020808252602d908201527f4261736520555249206368616e676520686173206265656e2064697361626c6560408201526c64207065726d616e656e746c7960981b606082015260800190565b6020808252601f908201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526031908201527f596f7520646f6e742068617665207065726d6973696f6e20746f20667265652060408201527036b4b73a103a3430ba1030b6b7bab73a1760791b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b60208082526022908201527f4d6f6c6c793a205075626c69632073616c6520686173206e6f74206163746976604082015261329760f11b606082015260800190565b60208082526022908201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604082015261756560f01b606082015260800190565b60208082526027908201527f4d6f6c6c793a2050726573616c65206973206e6f742063757272656e746c792060408201526630b1ba34bb329760c91b606082015260800190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252601b908201527f5349474e41545552455f56414c49444154494f4e5f4641494c45440000000000604082015260600190565b60208082526035908201527f4d6f6c6c793a2053656c656374656420616d6f756e74206578636565647320746040820152746865206d61782070726573616c6520737570706c7960581b606082015260800190565b6020808252603d908201527f5468652073616c65206f66204e465473206f6e20746865206d61726b6574706c60408201527f6163657320686173206e6f74206265656e206f70656e6564207965742e000000606082015260800190565b6020808252602e908201527f4d6f6c6c793a204d696e7420746f6f206c617267652c20657863656564696e6760408201526d20746865206d6178537570706c7960901b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b60208082526035908201527f4d6f6c6c793a204d696e7420746f6f206c617267652c20657863656564696e67604082015274081d1a1948199c9959481b5a5b9d08185b5bdd5b9d605a1b606082015260800190565b60208082526013908201527243414e2754205055542030204144445245535360681b604082015260600190565b60208082526022908201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604082015261756560f01b606082015260800190565b6020808252601c908201527f46726565206d696e74206973206e6f74206f70656e6564207965742e00000000604082015260600190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b60208082526010908201526f4d6f6c6c793a20536f6c64206f75742160801b604082015260600190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b6020808252818101527f596f75206d757374206d696e74206174206c65617374206f6e6520746f6b656e604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601f908201527f596f75206d757374206d696e74206174206c65617374206f6e65204e46542e00604082015260600190565b60208082526023908201527f4d6f6c6c793a20496e737566696369656e742045544820616d6f756e74207365604082015262373a1760e91b606082015260800190565b60208082526033908201527f4d6f6c6c793a20596f75206861766520657863656564656420746865206d6178604082015272207065722077616c6c657420616d6f756e742160681b606082015260800190565b6020808252602e908201527f4d6f6c6c793a2053656c656374656420616d6f756e742065786365656473207460408201526d34329036b0bc1039bab838363c9760911b606082015260800190565b6020808252602a908201527f4d6f6c6c793a20596f752063616e2774206d696e74206d6f7265207468616e206040820152696d617820737570706c7960b01b606082015260800190565b90815260200190565b6000821982111561392e5761392e613a13565b500190565b60008261394257613942613a29565b500490565b600081600019048311821515161561396157613961613a13565b500290565b60008282101561397857613978613a13565b500390565b60005b83811015613998578181015183820152602001613980565b838111156112f05750506000910152565b6002810460018216806139bd57607f821691505b602082108114156139de57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156139f8576139f8613a13565b5060010190565b600082613a0e57613a0e613a29565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114611d1057600080fdfea26469706673582212207cb07e47c04c51032920ca4d18dffaacdd3c09207e17399407f1a3f663e482f064736f6c63430008000033
Loading...
Loading
Loading...
Loading
[ 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.