Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Init Project | 16162510 | 767 days ago | IN | 0 ETH | 0.00936387 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
TwoFiveSixProject
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT /* 222222222222222 555555555555555555 66666666 2:::::::::::::::22 5::::::::::::::::5 6::::::6 2::::::222222:::::2 5::::::::::::::::5 6::::::6 2222222 2:::::2 5:::::555555555555 6::::::6 2:::::2 5:::::5 6::::::6 2:::::2 5:::::5 6::::::6 2222::::2 5:::::5555555555 6::::::6 22222::::::22 5:::::::::::::::5 6::::::::66666 22::::::::222 555555555555:::::5 6::::::::::::::66 2:::::22222 5:::::56::::::66666:::::6 2:::::2 5:::::56:::::6 6:::::6 2:::::2 5555555 5:::::56:::::6 6:::::6 2:::::2 2222225::::::55555::::::56::::::66666::::::6 2::::::2222222:::::2 55:::::::::::::55 66:::::::::::::66 2::::::::::::::::::2 55:::::::::55 66:::::::::66 22222222222222222222 555555555 666666666 Using this contract? A shout out to @Mint256Art is appreciated! */ pragma solidity ^0.8.13; import "./helpers/OwnableUpgradeable.sol"; import "./helpers/ERC721EnumerableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/Base64Upgradeable.sol"; contract TwoFiveSixProject is ERC721EnumerableUpgradeable, OwnableUpgradeable { uint256[180] public memberShipFlags; uint256[4] public gmTokenFlags; uint256[4] public grailersTokenFlags; string public baseURI; address public twoFiveSixGenesisAddress; address public gmTokenAddress; address public grailersAddress; uint256 public maxPerTx; uint256 public twoFiveSixShare; mapping(uint256 => bytes32) public tokenIdToHash; struct Project { string name; address payable artistAddress; address payable twoFiveSixFundsAddress; address artScriptAddress; address royaltyAddress; address owner; uint256 maxSupply; uint256 showCaseAmount; uint256 memberPrice; uint256 publicPrice; uint256 royalty; uint256 preSaleTimeStamp; uint256 publicTimetamp; bool memberOnly; } Project private project; function initProject( Project calldata p, uint256 _twoFiveSixShare, uint256 _maxPerTx, address _twoFiveSixGenesisAddress, address _gmTokenAddress, address _grailersAddress, string calldata _baseOfBase ) public initializer { __ERC721_init(p.name, "256ART"); __Ownable_init(p.owner); project = p; maxPerTx = _maxPerTx; twoFiveSixShare = _twoFiveSixShare; grailersAddress = _grailersAddress; gmTokenAddress = _gmTokenAddress; twoFiveSixGenesisAddress = _twoFiveSixGenesisAddress; baseURI = string( abi.encodePacked( _baseOfBase, _toLower(StringsUpgradeable.toHexString(address(this))), "/json_files/" ) ); } function tokenURI(uint256 _tokenId) public view override returns (string memory) { require(_exists(_tokenId), "Token not found"); return string( abi.encodePacked(baseURI, StringsUpgradeable.toString(_tokenId)) ); } function showCaseMint(uint256[] calldata the256ArtIds) public onlyOwner { uint256 count = the256ArtIds.length; uint256 totalSupply = _owners.length; require(totalSupply == 0, "Not first mint"); require(count == project.showCaseAmount, "Must mint all"); require(project.showCaseAmount % 2 == 0, "Must be even."); IERC721Upgradeable twoFiveSix = IERC721Upgradeable( twoFiveSixGenesisAddress ); for (uint256 i; i < count; i++) { require( twoFiveSix.ownerOf(the256ArtIds[i]) == _msgSender(), "Membership not owned" ); uint256 storedValue = getTokenIdForMembershipId(the256ArtIds[i]); bool unset = storedValue == 0; require(unset, "Membership already used"); } for (uint256 i; i < (project.showCaseAmount / 2); i++) { uint256 tokenId = totalSupply + i; uint256 tokenIdTwo = totalSupply + i + (project.showCaseAmount / 2); bytes32 hashOne = createHash(tokenId, msg.sender); tokenIdToHash[tokenId] = hashOne; _setTokenIdForMembershipId(the256ArtIds[i], tokenId); _mint(project.artistAddress, tokenId); bytes32 hashTwo = createHash(tokenIdTwo, msg.sender); tokenIdToHash[tokenIdTwo] = hashTwo; _setTokenIdForMembershipId( the256ArtIds[i + (project.showCaseAmount / 2)], tokenIdTwo ); _mint(project.twoFiveSixFundsAddress, tokenIdTwo); } } function memberMint(uint256[] calldata the256ArtIds, address a) public payable { uint256 totalSupply = _owners.length; uint256 count = the256ArtIds.length; require(project.preSaleTimeStamp < block.timestamp, "Sale not active"); require(count > 0, "Mint at least one"); require(totalSupply + count < project.maxSupply, "Exceeds max supply."); require(count < maxPerTx, "Exceeds max per transaction."); require( count * project.memberPrice <= msg.value, "Invalid funds provided." ); require(msg.sender == tx.origin, "No contract minting"); IERC721Upgradeable twoFiveSix = IERC721Upgradeable( twoFiveSixGenesisAddress ); for (uint256 i; i < count; i++) { require( twoFiveSix.ownerOf(the256ArtIds[i]) == a, "Membership not owned" ); uint256 tokenId = totalSupply + i; uint256 storedValue = getTokenIdForMembershipId(the256ArtIds[i]); bool unset = (storedValue == 0); require(unset, "Membership already used"); _setTokenIdForMembershipId(the256ArtIds[i], tokenId); bytes32 hashOne = createHash(tokenId, msg.sender); tokenIdToHash[tokenId] = hashOne; _mint(a, tokenId); } } function gmTokenMint(uint256[] calldata gmTokenIds, address a) public payable { uint256 totalSupply = _owners.length; uint256 count = gmTokenIds.length; require(project.preSaleTimeStamp < block.timestamp, "Sale not active"); require(!project.memberOnly, "Only members can mint."); require(count > 0, "Mint at least one"); require(totalSupply + count < project.maxSupply, "Exceeds max supply."); require(count < maxPerTx, "Exceeds max per transaction."); require( count * project.memberPrice <= msg.value, "Invalid funds provided." ); require(msg.sender == tx.origin, "No contract minting"); IERC721Upgradeable gmToken = IERC721Upgradeable(gmTokenAddress); for (uint256 i; i < count; i++) { require(gmToken.ownerOf(gmTokenIds[i]) == a, "GmToken not owned"); uint256 tokenId = totalSupply + i; bool isUsed = getGmTokenUsed(gmTokenIds[i]); require(!isUsed, "GmToken already used"); _setGmTokenUsed(gmTokenIds[i]); bytes32 hashOne = createHash(tokenId, msg.sender); tokenIdToHash[tokenId] = hashOne; _mint(a, tokenId); } } function grailersTokenMint(uint256[] calldata grailersTokenIds, address a) public payable { uint256 totalSupply = _owners.length; uint256 count = grailersTokenIds.length; require(project.preSaleTimeStamp < block.timestamp, "Sale not active"); require(!project.memberOnly, "Only members can mint."); require(count > 0, "Mint at least one"); require(totalSupply + count < project.maxSupply, "Exceeds max supply."); require(count < maxPerTx, "Exceeds max per transaction."); require( count * project.memberPrice <= msg.value, "Invalid funds provided." ); require(msg.sender == tx.origin, "No contract minting"); IERC721Upgradeable grailersToken = IERC721Upgradeable(gmTokenAddress); for (uint256 i; i < count; i++) { require( grailersToken.ownerOf(grailersTokenIds[i]) == a, "GrailersToken not owned" ); uint256 tokenId = totalSupply + i; bool isUsed = getGrailersTokenUsed(grailersTokenIds[i]); require(!isUsed, "GrailersToken already used"); _setGrailersTokenUsed(grailersTokenIds[i]); bytes32 hashOne = createHash(tokenId, msg.sender); tokenIdToHash[tokenId] = hashOne; _mint(a, tokenId); } } function publicMint(uint256 count, address a) public payable { uint256 totalSupply = _owners.length; require(project.publicTimetamp < block.timestamp, "Sale not active"); require(!project.memberOnly, "Only members can mint."); require(count > 0, "Mint at least one"); require(totalSupply + count < project.maxSupply, "Exceeds max supply."); require(count < maxPerTx, "Exceeds max per transaction."); require( count * project.publicPrice <= msg.value, "Invalid funds provided." ); require(msg.sender == tx.origin, "No contract minting"); for (uint256 i; i < count; i++) { uint256 tokenId = totalSupply + i; bytes32 hashOne = createHash(tokenId, msg.sender); tokenIdToHash[tokenId] = hashOne; _mint(a, tokenId); } } function createHash(uint256 tokenId, address sender) private view returns (bytes32) { return keccak256( abi.encodePacked( tokenId, sender, blockhash(block.number - 2), blockhash(block.number - 4), blockhash(block.number - 8) ) ); } function getHashFromTokenId(uint256 _id) public view returns (bytes32) { return tokenIdToHash[_id]; } function _setTokenIdForMembershipId(uint256 _membershipId, uint256 _tokenId) private { uint256 index = _membershipId / 23; uint256 bit = (_membershipId % 23) * 11; memberShipFlags[index] = (memberShipFlags[index] & ~(0x7FF << bit)) | (_tokenId << bit); } function _setGmTokenUsed(uint256 _gmTokenId) private { uint256 index = _gmTokenId / 256; uint256 bit = _gmTokenId % 256; gmTokenFlags[index] = gmTokenFlags[index] | (1 << bit); } function _setGrailersTokenUsed(uint256 _grailersTokenId) private { uint256 index = _grailersTokenId / 256; uint256 bit = _grailersTokenId % 256; grailersTokenFlags[index] = grailersTokenFlags[index] | (1 << bit); } function getTokenIdForMembershipId(uint256 _membershipId) public view returns (uint256) { uint256 index = _membershipId / 23; uint256 bit = (_membershipId % 23) * 11; uint256 storedValue = (memberShipFlags[index] >> bit) & 0x7FF; return storedValue; } function getMembershipIdForTokenId(uint256 tokenId) public view returns (uint256) { require(_exists(tokenId), "Token not found"); uint256[] memory allTokenIdsForMembershipIds = getAllTokenIdForMembershipId(); uint256 membershipId; for (uint256 i = 1; i < allTokenIdsForMembershipIds.length; i++) { if (allTokenIdsForMembershipIds[i] == tokenId) { membershipId = i; break; } } return membershipId; } function getGmTokenUsed(uint256 _gmTokenid) public view returns (bool) { uint256 index = _gmTokenid / 256; uint256 bit = _gmTokenid % 256; bool storedValue = ((gmTokenFlags[index] >> bit) & 1) > 0; return storedValue; } function getGrailersTokenUsed(uint256 _grailersTokenid) public view returns (bool) { uint256 index = _grailersTokenid / 256; uint256 bit = _grailersTokenid % 256; bool storedValue = ((grailersTokenFlags[index] >> bit) & 1) > 0; return storedValue; } function getAllTokenIdForMembershipId() public view returns (uint256[] memory) { uint256[] memory res = new uint256[](4096); for (uint256 i = 0; i < 4096; i++) { res[i] = getTokenIdForMembershipId(i); } return res; } function setBaseURI(string memory _baseURI) public onlyOwner { baseURI = _baseURI; } function setArtistAddress(address payable _artistAddress) external onlyOwner { project.artistAddress = _artistAddress; } function setTwoFiveSixFundsAddress(address payable _twoFiveSixFundsAddress) external onlyOwner { project.twoFiveSixFundsAddress = _twoFiveSixFundsAddress; } function setRoyalty(uint256 _royalty) external onlyOwner { project.royalty = _royalty; } function setRoyaltyAddress(address payable _royaltyAddress) external onlyOwner { project.royaltyAddress = _royaltyAddress; } function setArtScriptAddress(address _artScriptAddress) external onlyOwner { project.artScriptAddress = _artScriptAddress; } function setTwoFiveSixGenesisAddress(address _twoFiveSixGenesisAddress) external onlyOwner { twoFiveSixGenesisAddress = _twoFiveSixGenesisAddress; } function setMemberPrice(uint256 _price) external onlyOwner { project.memberPrice = _price; } function setPublicPrice(uint256 _price) external onlyOwner { project.publicPrice = _price; } function withdraw() public onlyOwner { uint256 balance = address(this).balance; project.twoFiveSixFundsAddress.transfer( (balance / 10000) * twoFiveSixShare ); project.artistAddress.transfer( (balance / 10000) * (10000 - twoFiveSixShare) ); } function walletOfOwner(address _owner) public view returns (uint256[] memory) { uint256 tokenCount = balanceOf(_owner); if (tokenCount == 0) return new uint256[](0); uint256[] memory tokensId = new uint256[](tokenCount); for (uint256 i; i < tokenCount; i++) { tokensId[i] = tokenOfOwnerByIndex(_owner, i); } return tokensId; } function batchTransferFrom( address _from, address _to, uint256[] memory _tokenIds ) public { for (uint256 i = 0; i < _tokenIds.length; i++) { transferFrom(_from, _to, _tokenIds[i]); } } function batchSafeTransferFrom( address _from, address _to, uint256[] memory _tokenIds, bytes memory data_ ) public { for (uint256 i = 0; i < _tokenIds.length; i++) { safeTransferFrom(_from, _to, _tokenIds[i], data_); } } function isOwnerOf(address account, uint256[] calldata _tokenIds) external view returns (bool) { for (uint256 i; i < _tokenIds.length; ++i) { if (_owners[_tokenIds[i]] != account) return false; } return true; } function _mint(address to, uint256 tokenId) internal virtual override { _owners.push(to); emit Transfer(address(0), to, tokenId); } function royaltyInfo(uint256, uint256 _salePrice) external view returns (address receiver, uint256 royaltyAmount) { return (project.royaltyAddress, (_salePrice * project.royalty) / 10000); } function toHex16(bytes16 data) internal pure returns (bytes32 result) { result = (bytes32(data) & 0xFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000) | ((bytes32(data) & 0x0000000000000000FFFFFFFFFFFFFFFF00000000000000000000000000000000) >> 64); result = (result & 0xFFFFFFFF000000000000000000000000FFFFFFFF000000000000000000000000) | ((result & 0x00000000FFFFFFFF000000000000000000000000FFFFFFFF0000000000000000) >> 32); result = (result & 0xFFFF000000000000FFFF000000000000FFFF000000000000FFFF000000000000) | ((result & 0x0000FFFF000000000000FFFF000000000000FFFF000000000000FFFF00000000) >> 16); result = (result & 0xFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000) | ((result & 0x00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000) >> 8); result = ((result & 0xF000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000) >> 4) | ((result & 0x0F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F00) >> 8); result = bytes32( 0x3030303030303030303030303030303030303030303030303030303030303030 + uint256(result) + (((uint256(result) + 0x0606060606060606060606060606060606060606060606060606060606060606) >> 4) & 0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F) * 7 ); } function _toLower(string memory str) internal pure returns (string memory) { bytes memory bStr = bytes(str); bytes memory bLower = new bytes(bStr.length); for (uint256 i = 0; i < bStr.length; i++) { // Uppercase character... if ((uint8(bStr[i]) >= 65) && (uint8(bStr[i]) <= 90)) { // So we add 32 to make it lowercase bLower[i] = bytes1(uint8(bStr[i]) + 32); } else { bLower[i] = bStr[i]; } } return string(bLower); } function toHex(bytes32 data) internal pure returns (string memory) { return string( abi.encodePacked( "0x", toHex16(bytes16(data)), toHex16(bytes16(data << 128)) ) ); } function getArtFromChain(uint256 tokenId) external view returns (string memory artwork) { require(_exists(tokenId), "Token not found"); uint256 membershipId = getMembershipIdForTokenId(tokenId); IArtScript artscript = IArtScript(project.artScriptAddress); return string( abi.encodePacked( "data:text/html;base64,", Base64Upgradeable.encode( abi.encodePacked( "<html><head><script>let inputData={'tokenId': ", StringsUpgradeable.toString(tokenId), ",'membershipId': ", StringsUpgradeable.toString(membershipId), ",'hash': '", toHex(getHashFromTokenId(tokenId)), "'}</script>", artscript.head(), "</head><body><script src='", artscript.externalLibrary(), "'></script>", "<script src='", artscript.twoFiveSixLibrary(), "'></script><script defer>", artscript.artScript(), "</script></body></html>" ) ) ) ); } //convenience project getters // Getter function for the name field of a private Project struct function projectName() external view returns (string memory) { return project.name; } // Getter function for the artistAddress field of a private Project struct function artistAddress() external view returns (address payable) { return project.artistAddress; } // Getter function for the twoFiveSixFundsAddress field of a private Project struct function twoFiveSixFundsAddress() external view returns (address payable) { return project.twoFiveSixFundsAddress; } // Getter function for the artScriptAddress field of a private Project struct function artScriptAddress() external view returns (address) { return project.artScriptAddress; } // Getter function for the royaltyAddress field of a private Project struct function royaltyAddress() external view returns (address) { return project.royaltyAddress; } // Getter function for the maxSupply field of a private Project struct function maxSupply() external view returns (uint256) { return project.maxSupply; } // Getter function for the showCaseAmount field of a private Project struct function showCaseAmount() external view returns (uint256) { return project.showCaseAmount; } // Getter function for the memberPrice field of a private Project struct function memberPrice() external view returns (uint256) { return project.memberPrice; } // Getter function for the publicPrice field of a private Project struct function publicPrice() external view returns (uint256) { return project.publicPrice; } // Getter function for the royalty field of a private Project struct function royalty() external view returns (uint256) { return project.royalty; } // Getter function for the preSaleTimeStamp field of a private Project struct function preSaleTimeStamp() external view returns (uint256) { return project.preSaleTimeStamp; } // Getter function for the publicTimetamp field of a private Project struct function publicTimetamp() external view returns (uint256) { return project.publicTimetamp; } // Getter function for the memberOnly field of a private Project struct function memberOnly() external view returns (bool) { return project.memberOnly; } } interface IArtScript { function projectName() external pure returns (string memory); function artistName() external pure returns (string memory); function externalLibrary() external pure returns (string memory); function twoFiveSixLibrary() external pure returns (string memory); function license() external pure returns (string memory); function artScript() external pure returns (string memory); function head() external pure returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.13; import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.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 OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init(address _ownerOnInit) internal onlyInitializing { __Ownable_init_unchained(_ownerOnInit); } function __Ownable_init_unchained(address _ownerOnInit) internal onlyInitializing { _transferOwnership(_ownerOnInit); } /** * @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); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import "./ERC721Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721EnumerableUpgradeable.sol"; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account but rips out the core of the gas-wasting processing that comes from OpenZeppelin. */ abstract contract ERC721EnumerableUpgradeable is ERC721Upgradeable, IERC721EnumerableUpgradeable { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC721Upgradeable) returns (bool) { return interfaceId == type(IERC721EnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _owners.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require( index < _owners.length, "ERC721Enumerable: global index out of bounds" ); return index; } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256 tokenId) { require( index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds" ); uint256 count; for (uint256 i; i < _owners.length; i++) { if (owner == _owners[i]) { if (count == index) return i; else count++; } } revert("ERC721Enumerable: owner index out of bounds"); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol) pragma solidity ^0.8.0; /** * @dev Provides a set of functions to operate with Base64 strings. * * _Available since v4.5._ */ library Base64Upgradeable { /** * @dev Base64 Encoding/Decoding Table */ string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * @dev Converts a `bytes` to its Bytes64 `string` representation. */ function encode(bytes memory data) internal pure returns (string memory) { /** * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol */ if (data.length == 0) return ""; // Loads the table into memory string memory table = _TABLE; // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter // and split into 4 numbers of 6 bits. // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up // - `data.length + 2` -> Round up // - `/ 3` -> Number of 3-bytes chunks // - `4 *` -> 4 characters for each chunk string memory result = new string(4 * ((data.length + 2) / 3)); /// @solidity memory-safe-assembly assembly { // Prepare the lookup table (skip the first "length" byte) let tablePtr := add(table, 1) // Prepare result pointer, jump over length let resultPtr := add(result, 32) // Run over the input, 3 bytes at a time for { let dataPtr := data let endPtr := add(data, mload(data)) } lt(dataPtr, endPtr) { } { // Advance 3 bytes dataPtr := add(dataPtr, 3) let input := mload(dataPtr) // To write each character, shift the 3 bytes (18 bits) chunk // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) // and apply logical AND with 0x3F which is the number of // the previous character in the ASCII table prior to the Base64 Table // The result is then added to the table to get the character to write, // and finally write it in the result pointer but with a left shift // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) resultPtr := add(resultPtr, 1) // Advance } // When data `bytes` is not exactly 3 bytes long // it is padded with `=` characters at the end switch mod(mload(data), 3) case 1 { mstore8(sub(resultPtr, 1), 0x3d) mstore8(sub(resultPtr, 2), 0x3d) } case 2 { mstore8(sub(resultPtr, 1), 0x3d) } } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @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 ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Internal function that returns the initialized version. Returns `_initialized` */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Internal function that returns the initialized version. Returns `_initializing` */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; import "./Address.sol"; abstract contract ERC721Upgradeable is ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable { using Address for address; using StringsUpgradeable for uint256; string private _name; string private _symbol; // Mapping from token ID to owner address address[] internal _owners; mapping(uint256 => address) private _tokenApprovals; mapping(address => mapping(address => bool)) private _operatorApprovals; function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC721_init_unchained(name_, symbol_); } function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC721Upgradeable).interfaceId || interfaceId == type(IERC721MetadataUpgradeable).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" ); uint256 count; for (uint256 i; i < _owners.length; ++i) { if (owner == _owners[i]) ++count; } return count; } /** * @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 {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721Upgradeable.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 { require(operator != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_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 tokenId < _owners.length && _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 = ERC721Upgradeable.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); _owners.push(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 = ERC721Upgradeable.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _owners[tokenId] = address(0); 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( ERC721Upgradeable.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); _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(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); } /** * @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 IERC721ReceiverUpgradeable(to).onERC721Received( _msgSender(), from, tokenId, _data ) returns (bytes4 retval) { return retval == IERC721ReceiverUpgradeable.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 (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../IERC721Upgradeable.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721EnumerableUpgradeable is IERC721Upgradeable { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721ReceiverUpgradeable { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721Upgradeable.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721MetadataUpgradeable is IERC721Upgradeable { /** * @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 (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/MathUpgradeable.sol"; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = MathUpgradeable.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, MathUpgradeable.log256(value) + 1); } } /** * @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] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.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 ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; library Address { function isContract(address account) internal view returns (bool) { uint256 size; assembly { size := extcodesize(account) } return size > 0; } }
// 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 IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","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":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"artScriptAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"artistAddress","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"bytes","name":"data_","type":"bytes"}],"name":"batchSafeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"batchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllTokenIdForMembershipId","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":"uint256","name":"tokenId","type":"uint256"}],"name":"getArtFromChain","outputs":[{"internalType":"string","name":"artwork","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gmTokenid","type":"uint256"}],"name":"getGmTokenUsed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_grailersTokenid","type":"uint256"}],"name":"getGrailersTokenUsed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getHashFromTokenId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getMembershipIdForTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_membershipId","type":"uint256"}],"name":"getTokenIdForMembershipId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gmTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"gmTokenFlags","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"gmTokenIds","type":"uint256[]"},{"internalType":"address","name":"a","type":"address"}],"name":"gmTokenMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"grailersAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"grailersTokenFlags","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"grailersTokenIds","type":"uint256[]"},{"internalType":"address","name":"a","type":"address"}],"name":"grailersTokenMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address payable","name":"artistAddress","type":"address"},{"internalType":"address payable","name":"twoFiveSixFundsAddress","type":"address"},{"internalType":"address","name":"artScriptAddress","type":"address"},{"internalType":"address","name":"royaltyAddress","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"uint256","name":"showCaseAmount","type":"uint256"},{"internalType":"uint256","name":"memberPrice","type":"uint256"},{"internalType":"uint256","name":"publicPrice","type":"uint256"},{"internalType":"uint256","name":"royalty","type":"uint256"},{"internalType":"uint256","name":"preSaleTimeStamp","type":"uint256"},{"internalType":"uint256","name":"publicTimetamp","type":"uint256"},{"internalType":"bool","name":"memberOnly","type":"bool"}],"internalType":"struct TwoFiveSixProject.Project","name":"p","type":"tuple"},{"internalType":"uint256","name":"_twoFiveSixShare","type":"uint256"},{"internalType":"uint256","name":"_maxPerTx","type":"uint256"},{"internalType":"address","name":"_twoFiveSixGenesisAddress","type":"address"},{"internalType":"address","name":"_gmTokenAddress","type":"address"},{"internalType":"address","name":"_grailersAddress","type":"address"},{"internalType":"string","name":"_baseOfBase","type":"string"}],"name":"initProject","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"isOwnerOf","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"the256ArtIds","type":"uint256[]"},{"internalType":"address","name":"a","type":"address"}],"name":"memberMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"memberOnly","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"memberPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"memberShipFlags","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":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"preSaleTimeStamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"projectName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"address","name":"a","type":"address"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"publicPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicTimetamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"royalty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_artScriptAddress","type":"address"}],"name":"setArtScriptAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_artistAddress","type":"address"}],"name":"setArtistAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setMemberPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPublicPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_royalty","type":"uint256"}],"name":"setRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_royaltyAddress","type":"address"}],"name":"setRoyaltyAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_twoFiveSixFundsAddress","type":"address"}],"name":"setTwoFiveSixFundsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_twoFiveSixGenesisAddress","type":"address"}],"name":"setTwoFiveSixGenesisAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"showCaseAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"the256ArtIds","type":"uint256[]"}],"name":"showCaseMint","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":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdToHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"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":"twoFiveSixFundsAddress","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"twoFiveSixGenesisAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"twoFiveSixShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50614fff806100206000396000f3fe6080604052600436106104045760003560e01c806370a0823111610213578063c627525511610123578063e133c8d2116100ab578063f2fde38b1161007a578063f2fde38b14610bff578063f3993d1114610c1f578063f510f51514610c3f578063f968adbe14610c5f578063fa8fb3f614610c7657600080fd5b8063e133c8d214610b6d578063e985e9c514610b80578063ee37349914610bc9578063f04e0f9a14610bde57600080fd5b8063ced48113116100f2578063ced4811314610ad8578063d27e149e14610af8578063d5abeb0114610b18578063d7eb3f3a14610b2e578063dfc6043614610b4d57600080fd5b8063c627525514610a61578063c87b56dd14610a81578063cb8f159514610aa1578063cd7a083c14610ac157600080fd5b8063a22cb465116101a6578063ad2f852a11610175578063ad2f852a146109c3578063b005f64a146109e2578063b55f0bc814610a02578063b88d4fde14610a21578063bfee9fc114610a4157600080fd5b8063a22cb4651461095a578063a22e4faa1461097a578063a8c9e3611461099a578063a945bf80146109ad57600080fd5b80638da5cb5b116101e25780638da5cb5b146108f357806395d89b41146109115780639a0bc582146109265780639a33e3001461094557600080fd5b806370a082311461087e578063715018a61461089e578063806c12e5146108b357806385eb939b146108d357600080fd5b806341a38e7f1161031957806355f804b3116102a15780636352211e116102705780636352211e146107fa578063636e746b1461081a578063674aa4df1461083057806369183cdf146108505780636c0360eb1461086957600080fd5b806355f804b3146107765780635a4fee30146107965780635ff4e604146107b6578063621a1f74146107cc57600080fd5b80634a328d5c116102e85780634a328d5c146106df5780634a7d348d146107005780634d44660c146107205780634e4bb94f146107405780634f6ccce71461075657600080fd5b806341a38e7f1461065f5780634209a2e11461067257806342842e0e14610692578063438b6300146106b257600080fd5b80631d306b2d1161039c57806329ee566c1161036b57806329ee566c146105b55780632a55205a146105cb5780632b5156921461060a5780632f745c591461062a5780633ccfd60b1461064a57600080fd5b80631d306b2d1461053e57806323b872dd1461055457806323c1e6ac14610574578063249431731461059557600080fd5b8063081812fc116103d8578063081812fc146104be578063095ea7b3146104f657806316069e9c1461051657806318160ddd1461052957600080fd5b8062c11be71461040957806301ffc9a71461044a57806306d254da1461047a57806306fdde031461049c575b600080fd5b34801561041557600080fd5b50610437610424366004613db1565b600090815261015e602052604090205490565b6040519081526020015b60405180910390f35b34801561045657600080fd5b5061046a610465366004613de0565b610c96565b6040519015158152602001610441565b34801561048657600080fd5b5061049a610495366004613e12565b610cc1565b005b3480156104a857600080fd5b506104b1610d17565b6040516104419190613e87565b3480156104ca57600080fd5b506104de6104d9366004613db1565b610da9565b6040516001600160a01b039091168152602001610441565b34801561050257600080fd5b5061049a610511366004613e9a565b610e31565b61049a610524366004613f0a565b610f46565b34801561053557600080fd5b50606754610437565b34801561054a57600080fd5b5061016a54610437565b34801561056057600080fd5b5061049a61056f366004613f60565b611220565b34801561058057600080fd5b5061015a546104de906001600160a01b031681565b3480156105a157600080fd5b5061049a6105b0366004613e12565b611251565b3480156105c157600080fd5b5061016954610437565b3480156105d757600080fd5b506105eb6105e6366004613fa1565b61129e565b604080516001600160a01b039093168352602083019190915201610441565b34801561061657600080fd5b5061046a610625366004613db1565b6112db565b34801561063657600080fd5b50610437610645366004613e9a565b611325565b34801561065657600080fd5b5061049a6113d7565b61049a61066d366004613fc3565b6114be565b34801561067e57600080fd5b5061049a61068d366004613db1565b61161f565b34801561069e57600080fd5b5061049a6106ad366004613f60565b61164f565b3480156106be57600080fd5b506106d26106cd366004613e12565b61166a565b6040516104419190613ff3565b3480156106eb57600080fd5b5061015b546104de906001600160a01b031681565b34801561070c57600080fd5b5061046a61071b366004613db1565b611725565b34801561072c57600080fd5b5061046a61073b366004614037565b61175e565b34801561074c57600080fd5b5061016654610437565b34801561076257600080fd5b50610437610771366004613db1565b6117e0565b34801561078257600080fd5b5061049a610791366004614136565b61184d565b3480156107a257600080fd5b5061049a6107b136600461421d565b61188b565b3480156107c257600080fd5b5061016b54610437565b3480156107d857600080fd5b506104376107e7366004613db1565b61015e6020526000908152604090205481565b34801561080657600080fd5b506104de610815366004613db1565b6118d5565b34801561082657600080fd5b5061016754610437565b34801561083c57600080fd5b5061043761084b366004613db1565b611961565b34801561085c57600080fd5b5061016c5460ff1661046a565b34801561087557600080fd5b506104b1611979565b34801561088a57600080fd5b50610437610899366004613e12565b611a08565b3480156108aa57600080fd5b5061049a611ad6565b3480156108bf57600080fd5b5061049a6108ce366004613db1565b611b0c565b3480156108df57600080fd5b506104376108ee366004613db1565b611b3c565b3480156108ff57600080fd5b50606a546001600160a01b03166104de565b34801561091d57600080fd5b506104b1611b8d565b34801561093257600080fd5b50610162546001600160a01b03166104de565b34801561095157600080fd5b506104b1611b9c565b34801561096657600080fd5b5061049a6109753660046142b3565b611baf565b34801561098657600080fd5b5061049a610995366004613e12565b611c73565b61049a6109a8366004613f0a565b611cc0565b3480156109b957600080fd5b5061016854610437565b3480156109cf57600080fd5b50610163546001600160a01b03166104de565b3480156109ee57600080fd5b506104376109fd366004613db1565b611f76565b348015610a0e57600080fd5b50610161546001600160a01b03166104de565b348015610a2d57600080fd5b5061049a610a3c3660046142e1565b611f87565b348015610a4d57600080fd5b5061049a610a5c366004613e12565b611fb9565b348015610a6d57600080fd5b5061049a610a7c366004613db1565b612006565b348015610a8d57600080fd5b506104b1610a9c366004613db1565b612036565b348015610aad57600080fd5b5061049a610abc366004613e12565b612090565b348015610acd57600080fd5b5061043761015d5481565b348015610ae457600080fd5b50610437610af3366004613db1565b6120dd565b348015610b0457600080fd5b50610437610b13366004613db1565b6120ed565b348015610b2457600080fd5b5061016554610437565b348015610b3a57600080fd5b50610160546001600160a01b03166104de565b348015610b5957600080fd5b5061049a610b68366004614340565b612168565b61049a610b7b366004613f0a565b6124f1565b348015610b8c57600080fd5b5061046a610b9b366004614381565b6001600160a01b03918216600090815260696020908152604080832093909416825291909152205460ff1690565b348015610bd557600080fd5b506106d26127d7565b348015610bea57600080fd5b50610159546104de906001600160a01b031681565b348015610c0b57600080fd5b5061049a610c1a366004613e12565b61284e565b348015610c2b57600080fd5b5061049a610c3a3660046143af565b6128e9565b348015610c4b57600080fd5b5061049a610c5a366004614451565b61292b565b348015610c6b57600080fd5b5061043761015c5481565b348015610c8257600080fd5b506104b1610c91366004613db1565b612b60565b60006001600160e01b0319821663780e9d6360e01b1480610cbb5750610cbb82612dba565b92915050565b606a546001600160a01b03163314610cf45760405162461bcd60e51b8152600401610ceb90614514565b60405180910390fd5b61016380546001600160a01b0319166001600160a01b0392909216919091179055565b606060658054610d2690614549565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5290614549565b8015610d9f5780601f10610d7457610100808354040283529160200191610d9f565b820191906000526020600020905b815481529060010190602001808311610d8257829003601f168201915b5050505050905090565b6000610db482612e0a565b610e155760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ceb565b506000908152606860205260409020546001600160a01b031690565b6000610e3c826118d5565b9050806001600160a01b0316836001600160a01b031603610ea95760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610ceb565b336001600160a01b0382161480610ec55750610ec58133610b9b565b610f375760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610ceb565b610f418383612e54565b505050565b60675461016a5483904211610f6d5760405162461bcd60e51b8152600401610ceb9061457d565b61016c5460ff1615610f915760405162461bcd60e51b8152600401610ceb906145a6565b60008111610fb15760405162461bcd60e51b8152600401610ceb906145d6565b61016554610fbf8284614617565b10610fdc5760405162461bcd60e51b8152600401610ceb9061462f565b61015c548110610ffe5760405162461bcd60e51b8152600401610ceb9061465c565b61016754349061100e9083614693565b111561102c5760405162461bcd60e51b8152600401610ceb906146b2565b33321461104b5760405162461bcd60e51b8152600401610ceb906146e9565b61015a546001600160a01b031660005b8281101561121757846001600160a01b0316826001600160a01b0316636352211e89898581811061108e5761108e614716565b905060200201356040518263ffffffff1660e01b81526004016110b391815260200190565b602060405180830381865afa1580156110d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f4919061472c565b6001600160a01b03161461113e5760405162461bcd60e51b815260206004820152601160248201527011db551bdad95b881b9bdd081bdddb9959607a1b6044820152606401610ceb565b600061114a8286614617565b9050600061116f89898581811061116357611163614716565b90506020020135611725565b905080156111b65760405162461bcd60e51b815260206004820152601460248201527311db551bdad95b88185b1c9958591e481d5cd95960621b6044820152606401610ceb565b6111d78989858181106111cb576111cb614716565b90506020020135612ec2565b60006111e38333612f18565b600084815261015e6020526040902081905590506112018884612fa2565b505050808061120f90614749565b91505061105b565b50505050505050565b61122a338261301e565b6112465760405162461bcd60e51b8152600401610ceb90614762565b610f41838383613108565b606a546001600160a01b0316331461127b5760405162461bcd60e51b8152600401610ceb90614514565b61016180546001600160a01b0319166001600160a01b0392909216919091179055565b610163546101695460009182916001600160a01b0390911690612710906112c59086614693565b6112cf91906147c9565b915091505b9250929050565b6000806112ea610100846147c9565b905060006112fa610100856147dd565b905060008082610154856004811061131457611314614716565b01546001911c161195945050505050565b600061133083611a08565b821061134e5760405162461bcd60e51b8152600401610ceb906147f1565b6000805b6067548110156113be576067818154811061136f5761136f614716565b6000918252602090912001546001600160a01b03908116908616036113ac5783820361139e579150610cbb9050565b816113a881614749565b9250505b806113b681614749565b915050611352565b5060405162461bcd60e51b8152600401610ceb906147f1565b606a546001600160a01b031633146114015760405162461bcd60e51b8152600401610ceb90614514565b6101615461015d5447916001600160a01b0316906108fc90611425612710856147c9565b61142f9190614693565b6040518115909202916000818181858888f19350505050158015611457573d6000803e3d6000fd5b506101605461015d546001600160a01b03909116906108fc9061147c9061271061483c565b611488612710856147c9565b6114929190614693565b6040518115909202916000818181858888f193505050501580156114ba573d6000803e3d6000fd5b5050565b60675461016b5442116114e35760405162461bcd60e51b8152600401610ceb9061457d565b61016c5460ff16156115075760405162461bcd60e51b8152600401610ceb906145a6565b600083116115275760405162461bcd60e51b8152600401610ceb906145d6565b610165546115358483614617565b106115525760405162461bcd60e51b8152600401610ceb9061462f565b61015c5483106115745760405162461bcd60e51b8152600401610ceb9061465c565b6101685434906115849085614693565b11156115a25760405162461bcd60e51b8152600401610ceb906146b2565b3332146115c15760405162461bcd60e51b8152600401610ceb906146e9565b60005b838110156116195760006115d88284614617565b905060006115e68233612f18565b600083815261015e6020526040902081905590506116048583612fa2565b5050808061161190614749565b9150506115c4565b50505050565b606a546001600160a01b031633146116495760405162461bcd60e51b8152600401610ceb90614514565b61016955565b610f4183838360405180602001604052806000815250611f87565b6060600061167783611a08565b90508060000361169b5760408051600080825260208201909252905b509392505050565b6000816001600160401b038111156116b5576116b561408b565b6040519080825280602002602001820160405280156116de578160200160208202803683370190505b50905060005b82811015611693576116f68582611325565b82828151811061170857611708614716565b60209081029190910101528061171d81614749565b9150506116e4565b600080611734610100846147c9565b90506000611744610100856147dd565b905060008082610150856004811061131457611314614716565b6000805b828110156117d357846001600160a01b0316606785858481811061178857611788614716565b905060200201358154811061179f5761179f614716565b6000918252602090912001546001600160a01b0316146117c35760009150506117d9565b6117cc81614749565b9050611762565b50600190505b9392505050565b60675460009082106118495760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610ceb565b5090565b606a546001600160a01b031633146118775760405162461bcd60e51b8152600401610ceb90614514565b80516114ba90610158906020840190613d21565b60005b82518110156118ce576118bc85858584815181106118ae576118ae614716565b602002602001015185611f87565b806118c681614749565b91505061188e565b5050505050565b600080606783815481106118eb576118eb614716565b6000918252602090912001546001600160a01b0316905080610cbb5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610ceb565b610154816004811061197257600080fd5b0154905081565b610158805461198790614549565b80601f01602080910402602001604051908101604052809291908181526020018280546119b390614549565b8015611a005780601f106119d557610100808354040283529160200191611a00565b820191906000526020600020905b8154815290600101906020018083116119e357829003601f168201915b505050505081565b60006001600160a01b038216611a735760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610ceb565b6000805b606754811015611acf5760678181548110611a9457611a94614716565b6000918252602090912001546001600160a01b0390811690851603611abf57611abc82614749565b91505b611ac881614749565b9050611a77565b5092915050565b606a546001600160a01b03163314611b005760405162461bcd60e51b8152600401610ceb90614514565b611b0a600061325e565b565b606a546001600160a01b03163314611b365760405162461bcd60e51b8152600401610ceb90614514565b61016755565b600080611b4a6017846147c9565b90506000611b596017856147dd565b611b6490600b614693565b9050600081609c8460b48110611b7c57611b7c614716565b01546107ff911c1695945050505050565b606060668054610d2690614549565b606061015f6000018054610d2690614549565b336001600160a01b03831603611c075760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610ceb565b3360008181526069602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b606a546001600160a01b03163314611c9d5760405162461bcd60e51b8152600401610ceb90614514565b61016080546001600160a01b0319166001600160a01b0392909216919091179055565b60675461016a5483904211611ce75760405162461bcd60e51b8152600401610ceb9061457d565b60008111611d075760405162461bcd60e51b8152600401610ceb906145d6565b61016554611d158284614617565b10611d325760405162461bcd60e51b8152600401610ceb9061462f565b61015c548110611d545760405162461bcd60e51b8152600401610ceb9061465c565b610167543490611d649083614693565b1115611d825760405162461bcd60e51b8152600401610ceb906146b2565b333214611da15760405162461bcd60e51b8152600401610ceb906146e9565b610159546001600160a01b031660005b8281101561121757846001600160a01b0316826001600160a01b0316636352211e898985818110611de457611de4614716565b905060200201356040518263ffffffff1660e01b8152600401611e0991815260200190565b602060405180830381865afa158015611e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4a919061472c565b6001600160a01b031614611e975760405162461bcd60e51b815260206004820152601460248201527313595b58995c9cda1a5c081b9bdd081bdddb995960621b6044820152606401610ceb565b6000611ea38286614617565b90506000611ec8898985818110611ebc57611ebc614716565b90506020020135611b3c565b9050801580611f135760405162461bcd60e51b815260206004820152601760248201527613595b58995c9cda1a5c08185b1c9958591e481d5cd959604a1b6044820152606401610ceb565b611f358a8a86818110611f2857611f28614716565b90506020020135846132b0565b6000611f418433612f18565b600085815261015e602052604090208190559050611f5f8985612fa2565b505050508080611f6e90614749565b915050611db1565b610150816004811061197257600080fd5b611f91338361301e565b611fad5760405162461bcd60e51b8152600401610ceb90614762565b61161984848484613314565b606a546001600160a01b03163314611fe35760405162461bcd60e51b8152600401610ceb90614514565b61015980546001600160a01b0319166001600160a01b0392909216919091179055565b606a546001600160a01b031633146120305760405162461bcd60e51b8152600401610ceb90614514565b61016855565b606061204182612e0a565b61205d5760405162461bcd60e51b8152600401610ceb90614853565b61015861206983613347565b60405160200161207a929190614898565b6040516020818303038152906040529050919050565b606a546001600160a01b031633146120ba5760405162461bcd60e51b8152600401610ceb90614514565b61016280546001600160a01b0319166001600160a01b0392909216919091179055565b609c8160b4811061197257600080fd5b60006120f882612e0a565b6121145760405162461bcd60e51b8152600401610ceb90614853565b600061211e6127d7565b9050600060015b8251811015611693578483828151811061214157612141614716565b60200260200101510361215657809150611693565b8061216081614749565b915050612125565b606a546001600160a01b031633146121925760405162461bcd60e51b8152600401610ceb90614514565b606754819080156121d65760405162461bcd60e51b815260206004820152600e60248201526d139bdd08199a5c9cdd081b5a5b9d60921b6044820152606401610ceb565b6101665482146122185760405162461bcd60e51b815260206004820152600d60248201526c135d5cdd081b5a5b9d08185b1b609a1b6044820152606401610ceb565b61016654612228906002906147dd565b156122655760405162461bcd60e51b815260206004820152600d60248201526c26bab9ba1031329032bb32b71760991b6044820152606401610ceb565b610159546001600160a01b031660005b838110156123c957336001600160a01b038316636352211e88888581811061229f5761229f614716565b905060200201356040518263ffffffff1660e01b81526004016122c491815260200190565b602060405180830381865afa1580156122e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612305919061472c565b6001600160a01b0316146123525760405162461bcd60e51b815260206004820152601460248201527313595b58995c9cda1a5c081b9bdd081bdddb995960621b6044820152606401610ceb565b6000612369878784818110611ebc57611ebc614716565b90508015806123b45760405162461bcd60e51b815260206004820152601760248201527613595b58995c9cda1a5c08185b1c9958591e481d5cd959604a1b6044820152606401610ceb565b505080806123c190614749565b915050612275565b5060005b610166546123dd906002906147c9565b8110156124e95760006123f08285614617565b90506000600261015f6007015461240791906147c9565b6124118487614617565b61241b9190614617565b905060006124298333612f18565b600084815261015e602052604090208190559050612452898986818110611f2857611f28614716565b61016054612469906001600160a01b031684612fa2565b60006124758333612f18565b600084815261015e60205260409020819055610166549091506124bb908b908b906124a2906002906147c9565b6124ac9089614617565b818110611f2857611f28614716565b610161546124d2906001600160a01b031684612fa2565b5050505080806124e190614749565b9150506123cd565b505050505050565b60675461016a54839042116125185760405162461bcd60e51b8152600401610ceb9061457d565b61016c5460ff161561253c5760405162461bcd60e51b8152600401610ceb906145a6565b6000811161255c5760405162461bcd60e51b8152600401610ceb906145d6565b6101655461256a8284614617565b106125875760405162461bcd60e51b8152600401610ceb9061462f565b61015c5481106125a95760405162461bcd60e51b8152600401610ceb9061465c565b6101675434906125b99083614693565b11156125d75760405162461bcd60e51b8152600401610ceb906146b2565b3332146125f65760405162461bcd60e51b8152600401610ceb906146e9565b61015a546001600160a01b031660005b8281101561121757846001600160a01b0316826001600160a01b0316636352211e89898581811061263957612639614716565b905060200201356040518263ffffffff1660e01b815260040161265e91815260200190565b602060405180830381865afa15801561267b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061269f919061472c565b6001600160a01b0316146126f55760405162461bcd60e51b815260206004820152601760248201527f477261696c657273546f6b656e206e6f74206f776e65640000000000000000006044820152606401610ceb565b60006127018286614617565b9050600061272689898581811061271a5761271a614716565b905060200201356112db565b905080156127765760405162461bcd60e51b815260206004820152601a60248201527f477261696c657273546f6b656e20616c726561647920757365640000000000006044820152606401610ceb565b61279789898581811061278b5761278b614716565b905060200201356133d9565b60006127a38333612f18565b600084815261015e6020526040902081905590506127c18884612fa2565b50505080806127cf90614749565b915050612606565b604080516110008082526202002082019092526060916000919060208201620200008036833701905050905060005b6110008110156128485761281981611b3c565b82828151811061282b5761282b614716565b60209081029190910101528061284081614749565b915050612806565b50919050565b606a546001600160a01b031633146128785760405162461bcd60e51b8152600401610ceb90614514565b6001600160a01b0381166128dd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ceb565b6128e68161325e565b50565b60005b815181101561161957612919848484848151811061290c5761290c614716565b6020026020010151611220565b8061292381614749565b9150506128ec565b600054610100900460ff161580801561294b5750600054600160ff909116105b806129655750303b158015612965575060005460ff166001145b6129c85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610ceb565b6000805460ff1916600117905580156129eb576000805461ff0019166101001790555b612a506129f88a8061491b565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260068152650c8d4d90549560d21b602082015291506134289050565b612a68612a6360c08b0160a08c01613e12565b613459565b8861015f612a768282614aa0565b505061015c87905561015d88905561015b80546001600160a01b038087166001600160a01b03199283161790925561015a80548884169083161790556101598054928916929091169190911790558282612ad7612ad230613489565b61349f565b604051602001612ae993929190614ba3565b6040516020818303038152906040526101589080519060200190612b0e929190613d21565b508015612b55576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050505050565b6060612b6b82612e0a565b612b875760405162461bcd60e51b8152600401610ceb90614853565b6000612b92836120ed565b610162549091506001600160a01b0316612d92612bae85613347565b612bb784613347565b600087815261015e6020526040902054612bd0906135f9565b846001600160a01b0316638f7dcfa36040518163ffffffff1660e01b8152600401600060405180830381865afa158015612c0e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c369190810190614be1565b856001600160a01b03166333a621e46040518163ffffffff1660e01b8152600401600060405180830381865afa158015612c74573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c9c9190810190614be1565b866001600160a01b031663c84f04316040518163ffffffff1660e01b8152600401600060405180830381865afa158015612cda573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612d029190810190614be1565b876001600160a01b031663091bb23e6040518163ffffffff1660e01b8152600401600060405180830381865afa158015612d40573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612d689190810190614be1565b604051602001612d7e9796959493929190614c57565b604051602081830303815290604052613634565b604051602001612da29190614e18565b60405160208183030381529060405292505050919050565b60006001600160e01b031982166380ac58cd60e01b1480612deb57506001600160e01b03198216635b5e139f60e01b145b80610cbb57506301ffc9a760e01b6001600160e01b0319831614610cbb565b60675460009082108015610cbb575060006001600160a01b031660678381548110612e3757612e37614716565b6000918252602090912001546001600160a01b0316141592915050565b600081815260686020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612e89826118d5565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000612ed0610100836147c9565b90506000612ee0610100846147dd565b90506001811b6101508360048110612efa57612efa614716565b0154176101508360048110612f1157612f11614716565b0155505050565b60008282612f2760024361483c565b40612f3360044361483c565b40612f3f60084361483c565b40604051602001612f8495949392919094855260609390931b6bffffffffffffffffffffffff1916602085015260348401919091526054830152607482015260940190565b60405160208183030381529060405280519060200120905092915050565b6067805460018101825560009182527f9787eeb91fe3101235e4a76063c7023ecb40f923f97916639c598592fa30d6ae0180546001600160a01b0319166001600160a01b0385169081179091556040518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600061302982612e0a565b61308a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ceb565b6000613095836118d5565b9050806001600160a01b0316846001600160a01b031614806130d05750836001600160a01b03166130c584610da9565b6001600160a01b0316145b8061310057506001600160a01b0380821660009081526069602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661311b826118d5565b6001600160a01b0316146131835760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610ceb565b6001600160a01b0382166131e55760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ceb565b6131f0600082612e54565b816067828154811061320457613204614716565b6000918252602082200180546001600160a01b0319166001600160a01b03938416179055604051839285811692908716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9190a4505050565b606a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006132bd6017846147c9565b905060006132cc6017856147dd565b6132d790600b614693565b905082811b6107ff821b19609c8460b481106132f5576132f5614716565b01541617609c8360b4811061330c5761330c614716565b015550505050565b61331f848484613108565b61332b84848484613786565b6116195760405162461bcd60e51b8152600401610ceb90614e56565b6060600061335483613887565b60010190506000816001600160401b038111156133735761337361408b565b6040519080825280601f01601f19166020018201604052801561339d576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846133a757509392505050565b60006133e7610100836147c9565b905060006133f7610100846147dd565b90506001811b610154836004811061341157613411614716565b0154176101548360048110612f1157612f11614716565b600054610100900460ff1661344f5760405162461bcd60e51b8152600401610ceb90614ea8565b6114ba828261395f565b600054610100900460ff166134805760405162461bcd60e51b8152600401610ceb90614ea8565b6128e6816139ad565b6060610cbb6001600160a01b03831660146139d4565b60606000829050600081516001600160401b038111156134c1576134c161408b565b6040519080825280601f01601f1916602001820160405280156134eb576020820181803683370190505b50905060005b825181101561169357604183828151811061350e5761350e614716565b016020015160f81c1080159061353e5750605a83828151811061353357613533614716565b016020015160f81c11155b156135a05782818151811061355557613555614716565b602001015160f81c60f81b60f81c602061356f9190614ef3565b60f81b82828151811061358457613584614716565b60200101906001600160f81b031916908160001a9053506135e7565b8281815181106135b2576135b2614716565b602001015160f81c60f81b8282815181106135cf576135cf614716565b60200101906001600160f81b031916908160001a9053505b806135f181614749565b9150506134f1565b606061360482613b6f565b613611608084901b613b6f565b60405161060f60f31b60208201526022810192909252604282015260620161207a565b6060815160000361365357505060408051602081019091526000815290565b6000604051806060016040528060408152602001614f8a60409139905060006003845160026136829190614617565b61368c91906147c9565b613697906004614693565b6001600160401b038111156136ae576136ae61408b565b6040519080825280601f01601f1916602001820160405280156136d8576020820181803683370190505b509050600182016020820185865187015b80821015613744576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453506001830192506136e9565b505060038651066001811461376057600281146137735761377b565b603d6001830353603d600283035361377b565b603d60018303535b509195945050505050565b60006001600160a01b0384163b1561387c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906137ca903390899088908890600401614f18565b6020604051808303816000875af1925050508015613805575060408051601f3d908101601f1916820190925261380291810190614f55565b60015b613862573d808015613833576040519150601f19603f3d011682016040523d82523d6000602084013e613838565b606091505b50805160000361385a5760405162461bcd60e51b8152600401610ceb90614e56565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050613100565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106138c65772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106138f2576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061391057662386f26fc10000830492506010015b6305f5e1008310613928576305f5e100830492506008015b612710831061393c57612710830492506004015b6064831061394e576064830492506002015b600a8310610cbb5760010192915050565b600054610100900460ff166139865760405162461bcd60e51b8152600401610ceb90614ea8565b8151613999906065906020850190613d21565b508051610f41906066906020840190613d21565b600054610100900460ff166128dd5760405162461bcd60e51b8152600401610ceb90614ea8565b606060006139e3836002614693565b6139ee906002614617565b6001600160401b03811115613a0557613a0561408b565b6040519080825280601f01601f191660200182016040528015613a2f576020820181803683370190505b509050600360fc1b81600081518110613a4a57613a4a614716565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613a7957613a79614716565b60200101906001600160f81b031916908160001a9053506000613a9d846002614693565b613aa8906001614617565b90505b6001811115613b20576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613adc57613adc614716565b1a60f81b828281518110613af257613af2614716565b60200101906001600160f81b031916908160001a90535060049490941c93613b1981614f72565b9050613aab565b5083156117d95760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610ceb565b7aff00000000000000ff00000000000000ff00000000000000ff00006bffffffff0000000000000000604083901c90811663ffffffff60c01b84161760201c63ffffffff60601b919091166001600160e01b031984161717601081901c9182167eff00000000000000ff00000000000000ff00000000000000ff000000000000821617600890811c7bff00000000000000ff00000000000000ff00000000000000ff000000939093167fff00000000000000ff00000000000000ff00000000000000ff000000000000009290921691909117919091179081901c7e0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f167f0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f00600492831c161790613cbd827f0606060606060606060606060606060606060606060606060606060606060606614617565b901c7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f166007613ced9190614693565b613d17827f3030303030303030303030303030303030303030303030303030303030303030614617565b610cbb9190614617565b828054613d2d90614549565b90600052602060002090601f016020900481019282613d4f5760008555613d95565b82601f10613d6857805160ff1916838001178555613d95565b82800160010185558215613d95579182015b82811115613d95578251825591602001919060010190613d7a565b506118499291505b808211156118495760008155600101613d9d565b600060208284031215613dc357600080fd5b5035919050565b6001600160e01b0319811681146128e657600080fd5b600060208284031215613df257600080fd5b81356117d981613dca565b6001600160a01b03811681146128e657600080fd5b600060208284031215613e2457600080fd5b81356117d981613dfd565b60005b83811015613e4a578181015183820152602001613e32565b838111156116195750506000910152565b60008151808452613e73816020860160208601613e2f565b601f01601f19169290920160200192915050565b6020815260006117d96020830184613e5b565b60008060408385031215613ead57600080fd5b8235613eb881613dfd565b946020939093013593505050565b60008083601f840112613ed857600080fd5b5081356001600160401b03811115613eef57600080fd5b6020830191508360208260051b85010111156112d457600080fd5b600080600060408486031215613f1f57600080fd5b83356001600160401b03811115613f3557600080fd5b613f4186828701613ec6565b9094509250506020840135613f5581613dfd565b809150509250925092565b600080600060608486031215613f7557600080fd5b8335613f8081613dfd565b92506020840135613f9081613dfd565b929592945050506040919091013590565b60008060408385031215613fb457600080fd5b50508035926020909101359150565b60008060408385031215613fd657600080fd5b823591506020830135613fe881613dfd565b809150509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561402b5783518352928401929184019160010161400f565b50909695505050505050565b60008060006040848603121561404c57600080fd5b833561405781613dfd565b925060208401356001600160401b0381111561407257600080fd5b61407e86828701613ec6565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156140c9576140c961408b565b604052919050565b60006001600160401b038211156140ea576140ea61408b565b50601f01601f191660200190565b600061410b614106846140d1565b6140a1565b905082815283838301111561411f57600080fd5b828260208301376000602084830101529392505050565b60006020828403121561414857600080fd5b81356001600160401b0381111561415e57600080fd5b8201601f8101841361416f57600080fd5b613100848235602084016140f8565b600082601f83011261418f57600080fd5b813560206001600160401b038211156141aa576141aa61408b565b8160051b6141b98282016140a1565b92835284810182019282810190878511156141d357600080fd5b83870192505b848310156141f2578235825291830191908301906141d9565b979650505050505050565b600082601f83011261420e57600080fd5b6117d9838335602085016140f8565b6000806000806080858703121561423357600080fd5b843561423e81613dfd565b9350602085013561424e81613dfd565b925060408501356001600160401b038082111561426a57600080fd5b6142768883890161417e565b9350606087013591508082111561428c57600080fd5b50614299878288016141fd565b91505092959194509250565b80151581146128e657600080fd5b600080604083850312156142c657600080fd5b82356142d181613dfd565b91506020830135613fe8816142a5565b600080600080608085870312156142f757600080fd5b843561430281613dfd565b9350602085013561431281613dfd565b92506040850135915060608501356001600160401b0381111561433457600080fd5b614299878288016141fd565b6000806020838503121561435357600080fd5b82356001600160401b0381111561436957600080fd5b61437585828601613ec6565b90969095509350505050565b6000806040838503121561439457600080fd5b823561439f81613dfd565b91506020830135613fe881613dfd565b6000806000606084860312156143c457600080fd5b83356143cf81613dfd565b925060208401356143df81613dfd565b915060408401356001600160401b038111156143fa57600080fd5b6144068682870161417e565b9150509250925092565b60008083601f84011261442257600080fd5b5081356001600160401b0381111561443957600080fd5b6020830191508360208285010111156112d457600080fd5b60008060008060008060008060e0898b03121561446d57600080fd5b88356001600160401b038082111561448457600080fd5b908a01906101c0828d03121561449957600080fd5b90985060208a0135975060408a0135965060608a0135906144b982613dfd565b90955060808a0135906144cb82613dfd565b90945060a08a0135906144dd82613dfd565b90935060c08a013590808211156144f357600080fd5b506145008b828c01614410565b999c989b5096995094979396929594505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600181811c9082168061455d57607f821691505b60208210810361284857634e487b7160e01b600052602260045260246000fd5b6020808252600f908201526e53616c65206e6f742061637469766560881b604082015260600190565b60208082526016908201527527b7363c9036b2b6b132b9399031b0b71036b4b73a1760511b604082015260600190565b6020808252601190820152704d696e74206174206c65617374206f6e6560781b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000821982111561462a5761462a614601565b500190565b60208082526013908201527222bc31b2b2b2399036b0bc1039bab838363c9760691b604082015260600190565b6020808252601c908201527f45786365656473206d617820706572207472616e73616374696f6e2e00000000604082015260600190565b60008160001904831182151516156146ad576146ad614601565b500290565b60208082526017908201527f496e76616c69642066756e64732070726f76696465642e000000000000000000604082015260600190565b6020808252601390820152724e6f20636f6e7472616374206d696e74696e6760681b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561473e57600080fd5b81516117d981613dfd565b60006001820161475b5761475b614601565b5060010190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b6000826147d8576147d86147b3565b500490565b6000826147ec576147ec6147b3565b500690565b6020808252602b908201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560408201526a74206f6620626f756e647360a81b606082015260800190565b60008282101561484e5761484e614601565b500390565b6020808252600f908201526e151bdad95b881b9bdd08199bdd5b99608a1b604082015260600190565b6000815161488e818560208601613e2f565b9290920192915050565b60008084546148a681614549565b600182811680156148be57600181146148cf576148fe565b60ff198416875282870194506148fe565b8860005260208060002060005b858110156148f55781548a8201529084019082016148dc565b50505082870194505b505050508351614912818360208801613e2f565b01949350505050565b6000808335601e1984360301811261493257600080fd5b8301803591506001600160401b0382111561494c57600080fd5b6020019150368190038213156112d457600080fd5b601f821115610f4157600081815260208120601f850160051c810160208610156149885750805b601f850160051c820191505b818110156124e957828155600101614994565b6001600160401b038311156149be576149be61408b565b6149d2836149cc8354614549565b83614961565b6000601f841160018114614a0657600085156149ee5750838201355b600019600387901b1c1916600186901b1783556118ce565b600083815260209020601f19861690835b82811015614a375786850135825560209485019460019092019101614a17565b5086821015614a545760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60008135610cbb81613dfd565b80546001600160a01b0319166001600160a01b0392909216919091179055565b60008135610cbb816142a5565b614aaa828361491b565b614ab58183856149a7565b5050614acf614ac660208401614a66565b60018301614a73565b614ae7614ade60408401614a66565b60028301614a73565b614aff614af660608401614a66565b60038301614a73565b614b17614b0e60808401614a66565b60048301614a73565b614b2f614b2660a08401614a66565b60058301614a73565b60c0820135600682015560e0820135600782015561010082013560088201556101208201356009820155610140820135600a820155610160820135600b820155610180820135600c8201556114ba614b8a6101a08401614a93565b600d830160ff1981541660ff8315151681178255505050565b828482376000838201600081528351614bc0818360208801613e2f565b6b2f6a736f6e5f66696c65732f60a01b9101908152600c0195945050505050565b600060208284031215614bf357600080fd5b81516001600160401b03811115614c0957600080fd5b8201601f81018413614c1a57600080fd5b8051614c28614106826140d1565b818152856020838501011115614c3d57600080fd5b614c4e826020830160208601613e2f565b95945050505050565b7f3c68746d6c3e3c686561643e3c7363726970743e6c657420696e70757444617481526d0309ebd93ba37b5b2b724b2139d160951b602082015260008851614ca681602e850160208d01613e2f565b7001613b6b2b6b132b939b434b824b2139d1607d1b602e918401918201528851614cd781603f840160208d01613e2f565b692c2768617368273a202760b01b603f92909101918201528751614d02816049840160208c01613e2f565b6a13be9e17b9b1b934b83a1f60a91b604992909101918201528651614d2e816054840160208b01613e2f565b614e09614de0614dda614db1614dab614d92614d7b614d756054898b01017f3c2f686561643e3c626f64793e3c736372697074207372633d270000000000008152601a0190565b8e61487c565b6a139f1e17b9b1b934b83a1f60a91b8152600b0190565b6c3c736372697074207372633d2760981b8152600d0190565b8a61487c565b7f273e3c2f7363726970743e3c7363726970742064656665723e00000000000000815260190190565b8761487c565b7f3c2f7363726970743e3c2f626f64793e3c2f68746d6c3e000000000000000000815260170190565b9b9a5050505050505050505050565b7519185d184e9d195e1d0bda1d1b5b0ed8985cd94d8d0b60521b815260008251614e49816016850160208701613e2f565b9190910160160192915050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600060ff821660ff84168060ff03821115614f1057614f10614601565b019392505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614f4b90830184613e5b565b9695505050505050565b600060208284031215614f6757600080fd5b81516117d981613dca565b600081614f8157614f81614601565b50600019019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa264697066735822122067e6a2ba7844b79b3351a0c3b425b633ae3d6dd33919983cde9e8457e571be4f64736f6c634300080d0033
Deployed Bytecode
0x6080604052600436106104045760003560e01c806370a0823111610213578063c627525511610123578063e133c8d2116100ab578063f2fde38b1161007a578063f2fde38b14610bff578063f3993d1114610c1f578063f510f51514610c3f578063f968adbe14610c5f578063fa8fb3f614610c7657600080fd5b8063e133c8d214610b6d578063e985e9c514610b80578063ee37349914610bc9578063f04e0f9a14610bde57600080fd5b8063ced48113116100f2578063ced4811314610ad8578063d27e149e14610af8578063d5abeb0114610b18578063d7eb3f3a14610b2e578063dfc6043614610b4d57600080fd5b8063c627525514610a61578063c87b56dd14610a81578063cb8f159514610aa1578063cd7a083c14610ac157600080fd5b8063a22cb465116101a6578063ad2f852a11610175578063ad2f852a146109c3578063b005f64a146109e2578063b55f0bc814610a02578063b88d4fde14610a21578063bfee9fc114610a4157600080fd5b8063a22cb4651461095a578063a22e4faa1461097a578063a8c9e3611461099a578063a945bf80146109ad57600080fd5b80638da5cb5b116101e25780638da5cb5b146108f357806395d89b41146109115780639a0bc582146109265780639a33e3001461094557600080fd5b806370a082311461087e578063715018a61461089e578063806c12e5146108b357806385eb939b146108d357600080fd5b806341a38e7f1161031957806355f804b3116102a15780636352211e116102705780636352211e146107fa578063636e746b1461081a578063674aa4df1461083057806369183cdf146108505780636c0360eb1461086957600080fd5b806355f804b3146107765780635a4fee30146107965780635ff4e604146107b6578063621a1f74146107cc57600080fd5b80634a328d5c116102e85780634a328d5c146106df5780634a7d348d146107005780634d44660c146107205780634e4bb94f146107405780634f6ccce71461075657600080fd5b806341a38e7f1461065f5780634209a2e11461067257806342842e0e14610692578063438b6300146106b257600080fd5b80631d306b2d1161039c57806329ee566c1161036b57806329ee566c146105b55780632a55205a146105cb5780632b5156921461060a5780632f745c591461062a5780633ccfd60b1461064a57600080fd5b80631d306b2d1461053e57806323b872dd1461055457806323c1e6ac14610574578063249431731461059557600080fd5b8063081812fc116103d8578063081812fc146104be578063095ea7b3146104f657806316069e9c1461051657806318160ddd1461052957600080fd5b8062c11be71461040957806301ffc9a71461044a57806306d254da1461047a57806306fdde031461049c575b600080fd5b34801561041557600080fd5b50610437610424366004613db1565b600090815261015e602052604090205490565b6040519081526020015b60405180910390f35b34801561045657600080fd5b5061046a610465366004613de0565b610c96565b6040519015158152602001610441565b34801561048657600080fd5b5061049a610495366004613e12565b610cc1565b005b3480156104a857600080fd5b506104b1610d17565b6040516104419190613e87565b3480156104ca57600080fd5b506104de6104d9366004613db1565b610da9565b6040516001600160a01b039091168152602001610441565b34801561050257600080fd5b5061049a610511366004613e9a565b610e31565b61049a610524366004613f0a565b610f46565b34801561053557600080fd5b50606754610437565b34801561054a57600080fd5b5061016a54610437565b34801561056057600080fd5b5061049a61056f366004613f60565b611220565b34801561058057600080fd5b5061015a546104de906001600160a01b031681565b3480156105a157600080fd5b5061049a6105b0366004613e12565b611251565b3480156105c157600080fd5b5061016954610437565b3480156105d757600080fd5b506105eb6105e6366004613fa1565b61129e565b604080516001600160a01b039093168352602083019190915201610441565b34801561061657600080fd5b5061046a610625366004613db1565b6112db565b34801561063657600080fd5b50610437610645366004613e9a565b611325565b34801561065657600080fd5b5061049a6113d7565b61049a61066d366004613fc3565b6114be565b34801561067e57600080fd5b5061049a61068d366004613db1565b61161f565b34801561069e57600080fd5b5061049a6106ad366004613f60565b61164f565b3480156106be57600080fd5b506106d26106cd366004613e12565b61166a565b6040516104419190613ff3565b3480156106eb57600080fd5b5061015b546104de906001600160a01b031681565b34801561070c57600080fd5b5061046a61071b366004613db1565b611725565b34801561072c57600080fd5b5061046a61073b366004614037565b61175e565b34801561074c57600080fd5b5061016654610437565b34801561076257600080fd5b50610437610771366004613db1565b6117e0565b34801561078257600080fd5b5061049a610791366004614136565b61184d565b3480156107a257600080fd5b5061049a6107b136600461421d565b61188b565b3480156107c257600080fd5b5061016b54610437565b3480156107d857600080fd5b506104376107e7366004613db1565b61015e6020526000908152604090205481565b34801561080657600080fd5b506104de610815366004613db1565b6118d5565b34801561082657600080fd5b5061016754610437565b34801561083c57600080fd5b5061043761084b366004613db1565b611961565b34801561085c57600080fd5b5061016c5460ff1661046a565b34801561087557600080fd5b506104b1611979565b34801561088a57600080fd5b50610437610899366004613e12565b611a08565b3480156108aa57600080fd5b5061049a611ad6565b3480156108bf57600080fd5b5061049a6108ce366004613db1565b611b0c565b3480156108df57600080fd5b506104376108ee366004613db1565b611b3c565b3480156108ff57600080fd5b50606a546001600160a01b03166104de565b34801561091d57600080fd5b506104b1611b8d565b34801561093257600080fd5b50610162546001600160a01b03166104de565b34801561095157600080fd5b506104b1611b9c565b34801561096657600080fd5b5061049a6109753660046142b3565b611baf565b34801561098657600080fd5b5061049a610995366004613e12565b611c73565b61049a6109a8366004613f0a565b611cc0565b3480156109b957600080fd5b5061016854610437565b3480156109cf57600080fd5b50610163546001600160a01b03166104de565b3480156109ee57600080fd5b506104376109fd366004613db1565b611f76565b348015610a0e57600080fd5b50610161546001600160a01b03166104de565b348015610a2d57600080fd5b5061049a610a3c3660046142e1565b611f87565b348015610a4d57600080fd5b5061049a610a5c366004613e12565b611fb9565b348015610a6d57600080fd5b5061049a610a7c366004613db1565b612006565b348015610a8d57600080fd5b506104b1610a9c366004613db1565b612036565b348015610aad57600080fd5b5061049a610abc366004613e12565b612090565b348015610acd57600080fd5b5061043761015d5481565b348015610ae457600080fd5b50610437610af3366004613db1565b6120dd565b348015610b0457600080fd5b50610437610b13366004613db1565b6120ed565b348015610b2457600080fd5b5061016554610437565b348015610b3a57600080fd5b50610160546001600160a01b03166104de565b348015610b5957600080fd5b5061049a610b68366004614340565b612168565b61049a610b7b366004613f0a565b6124f1565b348015610b8c57600080fd5b5061046a610b9b366004614381565b6001600160a01b03918216600090815260696020908152604080832093909416825291909152205460ff1690565b348015610bd557600080fd5b506106d26127d7565b348015610bea57600080fd5b50610159546104de906001600160a01b031681565b348015610c0b57600080fd5b5061049a610c1a366004613e12565b61284e565b348015610c2b57600080fd5b5061049a610c3a3660046143af565b6128e9565b348015610c4b57600080fd5b5061049a610c5a366004614451565b61292b565b348015610c6b57600080fd5b5061043761015c5481565b348015610c8257600080fd5b506104b1610c91366004613db1565b612b60565b60006001600160e01b0319821663780e9d6360e01b1480610cbb5750610cbb82612dba565b92915050565b606a546001600160a01b03163314610cf45760405162461bcd60e51b8152600401610ceb90614514565b60405180910390fd5b61016380546001600160a01b0319166001600160a01b0392909216919091179055565b606060658054610d2690614549565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5290614549565b8015610d9f5780601f10610d7457610100808354040283529160200191610d9f565b820191906000526020600020905b815481529060010190602001808311610d8257829003601f168201915b5050505050905090565b6000610db482612e0a565b610e155760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ceb565b506000908152606860205260409020546001600160a01b031690565b6000610e3c826118d5565b9050806001600160a01b0316836001600160a01b031603610ea95760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610ceb565b336001600160a01b0382161480610ec55750610ec58133610b9b565b610f375760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610ceb565b610f418383612e54565b505050565b60675461016a5483904211610f6d5760405162461bcd60e51b8152600401610ceb9061457d565b61016c5460ff1615610f915760405162461bcd60e51b8152600401610ceb906145a6565b60008111610fb15760405162461bcd60e51b8152600401610ceb906145d6565b61016554610fbf8284614617565b10610fdc5760405162461bcd60e51b8152600401610ceb9061462f565b61015c548110610ffe5760405162461bcd60e51b8152600401610ceb9061465c565b61016754349061100e9083614693565b111561102c5760405162461bcd60e51b8152600401610ceb906146b2565b33321461104b5760405162461bcd60e51b8152600401610ceb906146e9565b61015a546001600160a01b031660005b8281101561121757846001600160a01b0316826001600160a01b0316636352211e89898581811061108e5761108e614716565b905060200201356040518263ffffffff1660e01b81526004016110b391815260200190565b602060405180830381865afa1580156110d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f4919061472c565b6001600160a01b03161461113e5760405162461bcd60e51b815260206004820152601160248201527011db551bdad95b881b9bdd081bdddb9959607a1b6044820152606401610ceb565b600061114a8286614617565b9050600061116f89898581811061116357611163614716565b90506020020135611725565b905080156111b65760405162461bcd60e51b815260206004820152601460248201527311db551bdad95b88185b1c9958591e481d5cd95960621b6044820152606401610ceb565b6111d78989858181106111cb576111cb614716565b90506020020135612ec2565b60006111e38333612f18565b600084815261015e6020526040902081905590506112018884612fa2565b505050808061120f90614749565b91505061105b565b50505050505050565b61122a338261301e565b6112465760405162461bcd60e51b8152600401610ceb90614762565b610f41838383613108565b606a546001600160a01b0316331461127b5760405162461bcd60e51b8152600401610ceb90614514565b61016180546001600160a01b0319166001600160a01b0392909216919091179055565b610163546101695460009182916001600160a01b0390911690612710906112c59086614693565b6112cf91906147c9565b915091505b9250929050565b6000806112ea610100846147c9565b905060006112fa610100856147dd565b905060008082610154856004811061131457611314614716565b01546001911c161195945050505050565b600061133083611a08565b821061134e5760405162461bcd60e51b8152600401610ceb906147f1565b6000805b6067548110156113be576067818154811061136f5761136f614716565b6000918252602090912001546001600160a01b03908116908616036113ac5783820361139e579150610cbb9050565b816113a881614749565b9250505b806113b681614749565b915050611352565b5060405162461bcd60e51b8152600401610ceb906147f1565b606a546001600160a01b031633146114015760405162461bcd60e51b8152600401610ceb90614514565b6101615461015d5447916001600160a01b0316906108fc90611425612710856147c9565b61142f9190614693565b6040518115909202916000818181858888f19350505050158015611457573d6000803e3d6000fd5b506101605461015d546001600160a01b03909116906108fc9061147c9061271061483c565b611488612710856147c9565b6114929190614693565b6040518115909202916000818181858888f193505050501580156114ba573d6000803e3d6000fd5b5050565b60675461016b5442116114e35760405162461bcd60e51b8152600401610ceb9061457d565b61016c5460ff16156115075760405162461bcd60e51b8152600401610ceb906145a6565b600083116115275760405162461bcd60e51b8152600401610ceb906145d6565b610165546115358483614617565b106115525760405162461bcd60e51b8152600401610ceb9061462f565b61015c5483106115745760405162461bcd60e51b8152600401610ceb9061465c565b6101685434906115849085614693565b11156115a25760405162461bcd60e51b8152600401610ceb906146b2565b3332146115c15760405162461bcd60e51b8152600401610ceb906146e9565b60005b838110156116195760006115d88284614617565b905060006115e68233612f18565b600083815261015e6020526040902081905590506116048583612fa2565b5050808061161190614749565b9150506115c4565b50505050565b606a546001600160a01b031633146116495760405162461bcd60e51b8152600401610ceb90614514565b61016955565b610f4183838360405180602001604052806000815250611f87565b6060600061167783611a08565b90508060000361169b5760408051600080825260208201909252905b509392505050565b6000816001600160401b038111156116b5576116b561408b565b6040519080825280602002602001820160405280156116de578160200160208202803683370190505b50905060005b82811015611693576116f68582611325565b82828151811061170857611708614716565b60209081029190910101528061171d81614749565b9150506116e4565b600080611734610100846147c9565b90506000611744610100856147dd565b905060008082610150856004811061131457611314614716565b6000805b828110156117d357846001600160a01b0316606785858481811061178857611788614716565b905060200201358154811061179f5761179f614716565b6000918252602090912001546001600160a01b0316146117c35760009150506117d9565b6117cc81614749565b9050611762565b50600190505b9392505050565b60675460009082106118495760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610ceb565b5090565b606a546001600160a01b031633146118775760405162461bcd60e51b8152600401610ceb90614514565b80516114ba90610158906020840190613d21565b60005b82518110156118ce576118bc85858584815181106118ae576118ae614716565b602002602001015185611f87565b806118c681614749565b91505061188e565b5050505050565b600080606783815481106118eb576118eb614716565b6000918252602090912001546001600160a01b0316905080610cbb5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610ceb565b610154816004811061197257600080fd5b0154905081565b610158805461198790614549565b80601f01602080910402602001604051908101604052809291908181526020018280546119b390614549565b8015611a005780601f106119d557610100808354040283529160200191611a00565b820191906000526020600020905b8154815290600101906020018083116119e357829003601f168201915b505050505081565b60006001600160a01b038216611a735760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610ceb565b6000805b606754811015611acf5760678181548110611a9457611a94614716565b6000918252602090912001546001600160a01b0390811690851603611abf57611abc82614749565b91505b611ac881614749565b9050611a77565b5092915050565b606a546001600160a01b03163314611b005760405162461bcd60e51b8152600401610ceb90614514565b611b0a600061325e565b565b606a546001600160a01b03163314611b365760405162461bcd60e51b8152600401610ceb90614514565b61016755565b600080611b4a6017846147c9565b90506000611b596017856147dd565b611b6490600b614693565b9050600081609c8460b48110611b7c57611b7c614716565b01546107ff911c1695945050505050565b606060668054610d2690614549565b606061015f6000018054610d2690614549565b336001600160a01b03831603611c075760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610ceb565b3360008181526069602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b606a546001600160a01b03163314611c9d5760405162461bcd60e51b8152600401610ceb90614514565b61016080546001600160a01b0319166001600160a01b0392909216919091179055565b60675461016a5483904211611ce75760405162461bcd60e51b8152600401610ceb9061457d565b60008111611d075760405162461bcd60e51b8152600401610ceb906145d6565b61016554611d158284614617565b10611d325760405162461bcd60e51b8152600401610ceb9061462f565b61015c548110611d545760405162461bcd60e51b8152600401610ceb9061465c565b610167543490611d649083614693565b1115611d825760405162461bcd60e51b8152600401610ceb906146b2565b333214611da15760405162461bcd60e51b8152600401610ceb906146e9565b610159546001600160a01b031660005b8281101561121757846001600160a01b0316826001600160a01b0316636352211e898985818110611de457611de4614716565b905060200201356040518263ffffffff1660e01b8152600401611e0991815260200190565b602060405180830381865afa158015611e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4a919061472c565b6001600160a01b031614611e975760405162461bcd60e51b815260206004820152601460248201527313595b58995c9cda1a5c081b9bdd081bdddb995960621b6044820152606401610ceb565b6000611ea38286614617565b90506000611ec8898985818110611ebc57611ebc614716565b90506020020135611b3c565b9050801580611f135760405162461bcd60e51b815260206004820152601760248201527613595b58995c9cda1a5c08185b1c9958591e481d5cd959604a1b6044820152606401610ceb565b611f358a8a86818110611f2857611f28614716565b90506020020135846132b0565b6000611f418433612f18565b600085815261015e602052604090208190559050611f5f8985612fa2565b505050508080611f6e90614749565b915050611db1565b610150816004811061197257600080fd5b611f91338361301e565b611fad5760405162461bcd60e51b8152600401610ceb90614762565b61161984848484613314565b606a546001600160a01b03163314611fe35760405162461bcd60e51b8152600401610ceb90614514565b61015980546001600160a01b0319166001600160a01b0392909216919091179055565b606a546001600160a01b031633146120305760405162461bcd60e51b8152600401610ceb90614514565b61016855565b606061204182612e0a565b61205d5760405162461bcd60e51b8152600401610ceb90614853565b61015861206983613347565b60405160200161207a929190614898565b6040516020818303038152906040529050919050565b606a546001600160a01b031633146120ba5760405162461bcd60e51b8152600401610ceb90614514565b61016280546001600160a01b0319166001600160a01b0392909216919091179055565b609c8160b4811061197257600080fd5b60006120f882612e0a565b6121145760405162461bcd60e51b8152600401610ceb90614853565b600061211e6127d7565b9050600060015b8251811015611693578483828151811061214157612141614716565b60200260200101510361215657809150611693565b8061216081614749565b915050612125565b606a546001600160a01b031633146121925760405162461bcd60e51b8152600401610ceb90614514565b606754819080156121d65760405162461bcd60e51b815260206004820152600e60248201526d139bdd08199a5c9cdd081b5a5b9d60921b6044820152606401610ceb565b6101665482146122185760405162461bcd60e51b815260206004820152600d60248201526c135d5cdd081b5a5b9d08185b1b609a1b6044820152606401610ceb565b61016654612228906002906147dd565b156122655760405162461bcd60e51b815260206004820152600d60248201526c26bab9ba1031329032bb32b71760991b6044820152606401610ceb565b610159546001600160a01b031660005b838110156123c957336001600160a01b038316636352211e88888581811061229f5761229f614716565b905060200201356040518263ffffffff1660e01b81526004016122c491815260200190565b602060405180830381865afa1580156122e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612305919061472c565b6001600160a01b0316146123525760405162461bcd60e51b815260206004820152601460248201527313595b58995c9cda1a5c081b9bdd081bdddb995960621b6044820152606401610ceb565b6000612369878784818110611ebc57611ebc614716565b90508015806123b45760405162461bcd60e51b815260206004820152601760248201527613595b58995c9cda1a5c08185b1c9958591e481d5cd959604a1b6044820152606401610ceb565b505080806123c190614749565b915050612275565b5060005b610166546123dd906002906147c9565b8110156124e95760006123f08285614617565b90506000600261015f6007015461240791906147c9565b6124118487614617565b61241b9190614617565b905060006124298333612f18565b600084815261015e602052604090208190559050612452898986818110611f2857611f28614716565b61016054612469906001600160a01b031684612fa2565b60006124758333612f18565b600084815261015e60205260409020819055610166549091506124bb908b908b906124a2906002906147c9565b6124ac9089614617565b818110611f2857611f28614716565b610161546124d2906001600160a01b031684612fa2565b5050505080806124e190614749565b9150506123cd565b505050505050565b60675461016a54839042116125185760405162461bcd60e51b8152600401610ceb9061457d565b61016c5460ff161561253c5760405162461bcd60e51b8152600401610ceb906145a6565b6000811161255c5760405162461bcd60e51b8152600401610ceb906145d6565b6101655461256a8284614617565b106125875760405162461bcd60e51b8152600401610ceb9061462f565b61015c5481106125a95760405162461bcd60e51b8152600401610ceb9061465c565b6101675434906125b99083614693565b11156125d75760405162461bcd60e51b8152600401610ceb906146b2565b3332146125f65760405162461bcd60e51b8152600401610ceb906146e9565b61015a546001600160a01b031660005b8281101561121757846001600160a01b0316826001600160a01b0316636352211e89898581811061263957612639614716565b905060200201356040518263ffffffff1660e01b815260040161265e91815260200190565b602060405180830381865afa15801561267b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061269f919061472c565b6001600160a01b0316146126f55760405162461bcd60e51b815260206004820152601760248201527f477261696c657273546f6b656e206e6f74206f776e65640000000000000000006044820152606401610ceb565b60006127018286614617565b9050600061272689898581811061271a5761271a614716565b905060200201356112db565b905080156127765760405162461bcd60e51b815260206004820152601a60248201527f477261696c657273546f6b656e20616c726561647920757365640000000000006044820152606401610ceb565b61279789898581811061278b5761278b614716565b905060200201356133d9565b60006127a38333612f18565b600084815261015e6020526040902081905590506127c18884612fa2565b50505080806127cf90614749565b915050612606565b604080516110008082526202002082019092526060916000919060208201620200008036833701905050905060005b6110008110156128485761281981611b3c565b82828151811061282b5761282b614716565b60209081029190910101528061284081614749565b915050612806565b50919050565b606a546001600160a01b031633146128785760405162461bcd60e51b8152600401610ceb90614514565b6001600160a01b0381166128dd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ceb565b6128e68161325e565b50565b60005b815181101561161957612919848484848151811061290c5761290c614716565b6020026020010151611220565b8061292381614749565b9150506128ec565b600054610100900460ff161580801561294b5750600054600160ff909116105b806129655750303b158015612965575060005460ff166001145b6129c85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610ceb565b6000805460ff1916600117905580156129eb576000805461ff0019166101001790555b612a506129f88a8061491b565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260068152650c8d4d90549560d21b602082015291506134289050565b612a68612a6360c08b0160a08c01613e12565b613459565b8861015f612a768282614aa0565b505061015c87905561015d88905561015b80546001600160a01b038087166001600160a01b03199283161790925561015a80548884169083161790556101598054928916929091169190911790558282612ad7612ad230613489565b61349f565b604051602001612ae993929190614ba3565b6040516020818303038152906040526101589080519060200190612b0e929190613d21565b508015612b55576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050505050565b6060612b6b82612e0a565b612b875760405162461bcd60e51b8152600401610ceb90614853565b6000612b92836120ed565b610162549091506001600160a01b0316612d92612bae85613347565b612bb784613347565b600087815261015e6020526040902054612bd0906135f9565b846001600160a01b0316638f7dcfa36040518163ffffffff1660e01b8152600401600060405180830381865afa158015612c0e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c369190810190614be1565b856001600160a01b03166333a621e46040518163ffffffff1660e01b8152600401600060405180830381865afa158015612c74573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c9c9190810190614be1565b866001600160a01b031663c84f04316040518163ffffffff1660e01b8152600401600060405180830381865afa158015612cda573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612d029190810190614be1565b876001600160a01b031663091bb23e6040518163ffffffff1660e01b8152600401600060405180830381865afa158015612d40573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612d689190810190614be1565b604051602001612d7e9796959493929190614c57565b604051602081830303815290604052613634565b604051602001612da29190614e18565b60405160208183030381529060405292505050919050565b60006001600160e01b031982166380ac58cd60e01b1480612deb57506001600160e01b03198216635b5e139f60e01b145b80610cbb57506301ffc9a760e01b6001600160e01b0319831614610cbb565b60675460009082108015610cbb575060006001600160a01b031660678381548110612e3757612e37614716565b6000918252602090912001546001600160a01b0316141592915050565b600081815260686020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612e89826118d5565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000612ed0610100836147c9565b90506000612ee0610100846147dd565b90506001811b6101508360048110612efa57612efa614716565b0154176101508360048110612f1157612f11614716565b0155505050565b60008282612f2760024361483c565b40612f3360044361483c565b40612f3f60084361483c565b40604051602001612f8495949392919094855260609390931b6bffffffffffffffffffffffff1916602085015260348401919091526054830152607482015260940190565b60405160208183030381529060405280519060200120905092915050565b6067805460018101825560009182527f9787eeb91fe3101235e4a76063c7023ecb40f923f97916639c598592fa30d6ae0180546001600160a01b0319166001600160a01b0385169081179091556040518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600061302982612e0a565b61308a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ceb565b6000613095836118d5565b9050806001600160a01b0316846001600160a01b031614806130d05750836001600160a01b03166130c584610da9565b6001600160a01b0316145b8061310057506001600160a01b0380821660009081526069602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661311b826118d5565b6001600160a01b0316146131835760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610ceb565b6001600160a01b0382166131e55760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ceb565b6131f0600082612e54565b816067828154811061320457613204614716565b6000918252602082200180546001600160a01b0319166001600160a01b03938416179055604051839285811692908716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9190a4505050565b606a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006132bd6017846147c9565b905060006132cc6017856147dd565b6132d790600b614693565b905082811b6107ff821b19609c8460b481106132f5576132f5614716565b01541617609c8360b4811061330c5761330c614716565b015550505050565b61331f848484613108565b61332b84848484613786565b6116195760405162461bcd60e51b8152600401610ceb90614e56565b6060600061335483613887565b60010190506000816001600160401b038111156133735761337361408b565b6040519080825280601f01601f19166020018201604052801561339d576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846133a757509392505050565b60006133e7610100836147c9565b905060006133f7610100846147dd565b90506001811b610154836004811061341157613411614716565b0154176101548360048110612f1157612f11614716565b600054610100900460ff1661344f5760405162461bcd60e51b8152600401610ceb90614ea8565b6114ba828261395f565b600054610100900460ff166134805760405162461bcd60e51b8152600401610ceb90614ea8565b6128e6816139ad565b6060610cbb6001600160a01b03831660146139d4565b60606000829050600081516001600160401b038111156134c1576134c161408b565b6040519080825280601f01601f1916602001820160405280156134eb576020820181803683370190505b50905060005b825181101561169357604183828151811061350e5761350e614716565b016020015160f81c1080159061353e5750605a83828151811061353357613533614716565b016020015160f81c11155b156135a05782818151811061355557613555614716565b602001015160f81c60f81b60f81c602061356f9190614ef3565b60f81b82828151811061358457613584614716565b60200101906001600160f81b031916908160001a9053506135e7565b8281815181106135b2576135b2614716565b602001015160f81c60f81b8282815181106135cf576135cf614716565b60200101906001600160f81b031916908160001a9053505b806135f181614749565b9150506134f1565b606061360482613b6f565b613611608084901b613b6f565b60405161060f60f31b60208201526022810192909252604282015260620161207a565b6060815160000361365357505060408051602081019091526000815290565b6000604051806060016040528060408152602001614f8a60409139905060006003845160026136829190614617565b61368c91906147c9565b613697906004614693565b6001600160401b038111156136ae576136ae61408b565b6040519080825280601f01601f1916602001820160405280156136d8576020820181803683370190505b509050600182016020820185865187015b80821015613744576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453506001830192506136e9565b505060038651066001811461376057600281146137735761377b565b603d6001830353603d600283035361377b565b603d60018303535b509195945050505050565b60006001600160a01b0384163b1561387c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906137ca903390899088908890600401614f18565b6020604051808303816000875af1925050508015613805575060408051601f3d908101601f1916820190925261380291810190614f55565b60015b613862573d808015613833576040519150601f19603f3d011682016040523d82523d6000602084013e613838565b606091505b50805160000361385a5760405162461bcd60e51b8152600401610ceb90614e56565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050613100565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106138c65772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106138f2576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061391057662386f26fc10000830492506010015b6305f5e1008310613928576305f5e100830492506008015b612710831061393c57612710830492506004015b6064831061394e576064830492506002015b600a8310610cbb5760010192915050565b600054610100900460ff166139865760405162461bcd60e51b8152600401610ceb90614ea8565b8151613999906065906020850190613d21565b508051610f41906066906020840190613d21565b600054610100900460ff166128dd5760405162461bcd60e51b8152600401610ceb90614ea8565b606060006139e3836002614693565b6139ee906002614617565b6001600160401b03811115613a0557613a0561408b565b6040519080825280601f01601f191660200182016040528015613a2f576020820181803683370190505b509050600360fc1b81600081518110613a4a57613a4a614716565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613a7957613a79614716565b60200101906001600160f81b031916908160001a9053506000613a9d846002614693565b613aa8906001614617565b90505b6001811115613b20576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613adc57613adc614716565b1a60f81b828281518110613af257613af2614716565b60200101906001600160f81b031916908160001a90535060049490941c93613b1981614f72565b9050613aab565b5083156117d95760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610ceb565b7aff00000000000000ff00000000000000ff00000000000000ff00006bffffffff0000000000000000604083901c90811663ffffffff60c01b84161760201c63ffffffff60601b919091166001600160e01b031984161717601081901c9182167eff00000000000000ff00000000000000ff00000000000000ff000000000000821617600890811c7bff00000000000000ff00000000000000ff00000000000000ff000000939093167fff00000000000000ff00000000000000ff00000000000000ff000000000000009290921691909117919091179081901c7e0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f167f0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f00600492831c161790613cbd827f0606060606060606060606060606060606060606060606060606060606060606614617565b901c7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f166007613ced9190614693565b613d17827f3030303030303030303030303030303030303030303030303030303030303030614617565b610cbb9190614617565b828054613d2d90614549565b90600052602060002090601f016020900481019282613d4f5760008555613d95565b82601f10613d6857805160ff1916838001178555613d95565b82800160010185558215613d95579182015b82811115613d95578251825591602001919060010190613d7a565b506118499291505b808211156118495760008155600101613d9d565b600060208284031215613dc357600080fd5b5035919050565b6001600160e01b0319811681146128e657600080fd5b600060208284031215613df257600080fd5b81356117d981613dca565b6001600160a01b03811681146128e657600080fd5b600060208284031215613e2457600080fd5b81356117d981613dfd565b60005b83811015613e4a578181015183820152602001613e32565b838111156116195750506000910152565b60008151808452613e73816020860160208601613e2f565b601f01601f19169290920160200192915050565b6020815260006117d96020830184613e5b565b60008060408385031215613ead57600080fd5b8235613eb881613dfd565b946020939093013593505050565b60008083601f840112613ed857600080fd5b5081356001600160401b03811115613eef57600080fd5b6020830191508360208260051b85010111156112d457600080fd5b600080600060408486031215613f1f57600080fd5b83356001600160401b03811115613f3557600080fd5b613f4186828701613ec6565b9094509250506020840135613f5581613dfd565b809150509250925092565b600080600060608486031215613f7557600080fd5b8335613f8081613dfd565b92506020840135613f9081613dfd565b929592945050506040919091013590565b60008060408385031215613fb457600080fd5b50508035926020909101359150565b60008060408385031215613fd657600080fd5b823591506020830135613fe881613dfd565b809150509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561402b5783518352928401929184019160010161400f565b50909695505050505050565b60008060006040848603121561404c57600080fd5b833561405781613dfd565b925060208401356001600160401b0381111561407257600080fd5b61407e86828701613ec6565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156140c9576140c961408b565b604052919050565b60006001600160401b038211156140ea576140ea61408b565b50601f01601f191660200190565b600061410b614106846140d1565b6140a1565b905082815283838301111561411f57600080fd5b828260208301376000602084830101529392505050565b60006020828403121561414857600080fd5b81356001600160401b0381111561415e57600080fd5b8201601f8101841361416f57600080fd5b613100848235602084016140f8565b600082601f83011261418f57600080fd5b813560206001600160401b038211156141aa576141aa61408b565b8160051b6141b98282016140a1565b92835284810182019282810190878511156141d357600080fd5b83870192505b848310156141f2578235825291830191908301906141d9565b979650505050505050565b600082601f83011261420e57600080fd5b6117d9838335602085016140f8565b6000806000806080858703121561423357600080fd5b843561423e81613dfd565b9350602085013561424e81613dfd565b925060408501356001600160401b038082111561426a57600080fd5b6142768883890161417e565b9350606087013591508082111561428c57600080fd5b50614299878288016141fd565b91505092959194509250565b80151581146128e657600080fd5b600080604083850312156142c657600080fd5b82356142d181613dfd565b91506020830135613fe8816142a5565b600080600080608085870312156142f757600080fd5b843561430281613dfd565b9350602085013561431281613dfd565b92506040850135915060608501356001600160401b0381111561433457600080fd5b614299878288016141fd565b6000806020838503121561435357600080fd5b82356001600160401b0381111561436957600080fd5b61437585828601613ec6565b90969095509350505050565b6000806040838503121561439457600080fd5b823561439f81613dfd565b91506020830135613fe881613dfd565b6000806000606084860312156143c457600080fd5b83356143cf81613dfd565b925060208401356143df81613dfd565b915060408401356001600160401b038111156143fa57600080fd5b6144068682870161417e565b9150509250925092565b60008083601f84011261442257600080fd5b5081356001600160401b0381111561443957600080fd5b6020830191508360208285010111156112d457600080fd5b60008060008060008060008060e0898b03121561446d57600080fd5b88356001600160401b038082111561448457600080fd5b908a01906101c0828d03121561449957600080fd5b90985060208a0135975060408a0135965060608a0135906144b982613dfd565b90955060808a0135906144cb82613dfd565b90945060a08a0135906144dd82613dfd565b90935060c08a013590808211156144f357600080fd5b506145008b828c01614410565b999c989b5096995094979396929594505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600181811c9082168061455d57607f821691505b60208210810361284857634e487b7160e01b600052602260045260246000fd5b6020808252600f908201526e53616c65206e6f742061637469766560881b604082015260600190565b60208082526016908201527527b7363c9036b2b6b132b9399031b0b71036b4b73a1760511b604082015260600190565b6020808252601190820152704d696e74206174206c65617374206f6e6560781b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000821982111561462a5761462a614601565b500190565b60208082526013908201527222bc31b2b2b2399036b0bc1039bab838363c9760691b604082015260600190565b6020808252601c908201527f45786365656473206d617820706572207472616e73616374696f6e2e00000000604082015260600190565b60008160001904831182151516156146ad576146ad614601565b500290565b60208082526017908201527f496e76616c69642066756e64732070726f76696465642e000000000000000000604082015260600190565b6020808252601390820152724e6f20636f6e7472616374206d696e74696e6760681b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561473e57600080fd5b81516117d981613dfd565b60006001820161475b5761475b614601565b5060010190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b6000826147d8576147d86147b3565b500490565b6000826147ec576147ec6147b3565b500690565b6020808252602b908201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560408201526a74206f6620626f756e647360a81b606082015260800190565b60008282101561484e5761484e614601565b500390565b6020808252600f908201526e151bdad95b881b9bdd08199bdd5b99608a1b604082015260600190565b6000815161488e818560208601613e2f565b9290920192915050565b60008084546148a681614549565b600182811680156148be57600181146148cf576148fe565b60ff198416875282870194506148fe565b8860005260208060002060005b858110156148f55781548a8201529084019082016148dc565b50505082870194505b505050508351614912818360208801613e2f565b01949350505050565b6000808335601e1984360301811261493257600080fd5b8301803591506001600160401b0382111561494c57600080fd5b6020019150368190038213156112d457600080fd5b601f821115610f4157600081815260208120601f850160051c810160208610156149885750805b601f850160051c820191505b818110156124e957828155600101614994565b6001600160401b038311156149be576149be61408b565b6149d2836149cc8354614549565b83614961565b6000601f841160018114614a0657600085156149ee5750838201355b600019600387901b1c1916600186901b1783556118ce565b600083815260209020601f19861690835b82811015614a375786850135825560209485019460019092019101614a17565b5086821015614a545760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60008135610cbb81613dfd565b80546001600160a01b0319166001600160a01b0392909216919091179055565b60008135610cbb816142a5565b614aaa828361491b565b614ab58183856149a7565b5050614acf614ac660208401614a66565b60018301614a73565b614ae7614ade60408401614a66565b60028301614a73565b614aff614af660608401614a66565b60038301614a73565b614b17614b0e60808401614a66565b60048301614a73565b614b2f614b2660a08401614a66565b60058301614a73565b60c0820135600682015560e0820135600782015561010082013560088201556101208201356009820155610140820135600a820155610160820135600b820155610180820135600c8201556114ba614b8a6101a08401614a93565b600d830160ff1981541660ff8315151681178255505050565b828482376000838201600081528351614bc0818360208801613e2f565b6b2f6a736f6e5f66696c65732f60a01b9101908152600c0195945050505050565b600060208284031215614bf357600080fd5b81516001600160401b03811115614c0957600080fd5b8201601f81018413614c1a57600080fd5b8051614c28614106826140d1565b818152856020838501011115614c3d57600080fd5b614c4e826020830160208601613e2f565b95945050505050565b7f3c68746d6c3e3c686561643e3c7363726970743e6c657420696e70757444617481526d0309ebd93ba37b5b2b724b2139d160951b602082015260008851614ca681602e850160208d01613e2f565b7001613b6b2b6b132b939b434b824b2139d1607d1b602e918401918201528851614cd781603f840160208d01613e2f565b692c2768617368273a202760b01b603f92909101918201528751614d02816049840160208c01613e2f565b6a13be9e17b9b1b934b83a1f60a91b604992909101918201528651614d2e816054840160208b01613e2f565b614e09614de0614dda614db1614dab614d92614d7b614d756054898b01017f3c2f686561643e3c626f64793e3c736372697074207372633d270000000000008152601a0190565b8e61487c565b6a139f1e17b9b1b934b83a1f60a91b8152600b0190565b6c3c736372697074207372633d2760981b8152600d0190565b8a61487c565b7f273e3c2f7363726970743e3c7363726970742064656665723e00000000000000815260190190565b8761487c565b7f3c2f7363726970743e3c2f626f64793e3c2f68746d6c3e000000000000000000815260170190565b9b9a5050505050505050505050565b7519185d184e9d195e1d0bda1d1b5b0ed8985cd94d8d0b60521b815260008251614e49816016850160208701613e2f565b9190910160160192915050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600060ff821660ff84168060ff03821115614f1057614f10614601565b019392505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614f4b90830184613e5b565b9695505050505050565b600060208284031215614f6757600080fd5b81516117d981613dca565b600081614f8157614f81614601565b50600019019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa264697066735822122067e6a2ba7844b79b3351a0c3b425b633ae3d6dd33919983cde9e8457e571be4f64736f6c634300080d0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.