Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Overview
Max Total Supply
27 🟪️✅
Holders
20
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 🟪️✅Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Purplecheck
Compiler Version
v0.8.16+commit.07a7930e
Optimization Enabled:
Yes with 200000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.13; import {ERC721} from "solmate/tokens/ERC721.sol"; import {Owned} from "solmate/auth/Owned.sol"; import {LinearVRGDA} from "VRGDAs/LinearVRGDA.sol"; import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol"; import {toDaysWadUnsafe} from "solmate/utils/SignedWadMath.sol"; import {Metadata} from "./Metadata.sol"; /// @title Purplecheck - Your JPEGs deserve to feel special. /// @notice Mint an ERC721 token associated with an IPFS content ID. /// Mint price is calculated by a linear VRGDA targeting 6.9 purplechecks /// per day at a price of 0.00420 ETH. /// @author horsefacts <[email protected]> contract Purplecheck is ERC721, LinearVRGDA, Owned { /// @notice Total number of Purplecheck tokens. uint256 public totalSupply; /// @notice Mint start time. Used in VRGDA price calculations. uint256 public immutable startTime = block.timestamp; /// @notice tokenId => IPFS CIDv1 mapping(uint256 => string) public cid; constructor(address owner) ERC721("Purplecheck", unicode"🟪️✅") // Target rate 6.9 per day @ 0.00420 ETH LinearVRGDA(0.0042e18, 0.31e18, 6.9e18) Owned(owner) {} /// @notice Get the contract URI for this contract, encoded as a data URI. /// @return Contract metadata URI. function contractURI() external pure returns (string memory) { return Metadata.contractURI(); } /// @notice Get the metadata URI for the given token ID, encoded as a data URI. /// @param tokenId uint256 token ID. /// @return Metadata URI. function tokenURI(uint256 tokenId) public view override returns (string memory) { return Metadata.tokenURI(tokenId, imageURI(tokenId)); } /// @notice Get the IPFS image URI for the given token ID. /// @param tokenId uint256 token ID. /// @return URI of given token ID. function imageURI(uint256 tokenId) public view returns (string memory) { return Metadata.toImageURI(cid[tokenId]); } /// @notice Current mint price of a Purplecheck token, based on block.timestamp. /// @return uint256 mint price in wei. function price() public view returns (uint256) { return getVRGDAPrice(toDaysWadUnsafe(block.timestamp - startTime), totalSupply); } /// @notice Mint a Purplecheck token. /// @param _cid IPFS CIDv1 of the associated image. /// @return tokenId uint256 token ID. function mint(string calldata _cid) external payable returns (uint256 tokenId) { unchecked { // Get current VRGDA price uint256 _price = price(); // Revert if caller has underpaid require(msg.value >= _price, "UNDERPAID"); // Increment total supply and store image CID cid[tokenId = ++totalSupply] = _cid; // Mint token to caller _mint(msg.sender, tokenId); // Refund excess payment to caller if (msg.value != _price) SafeTransferLib.safeTransferETH(msg.sender, msg.value - _price); } } /// @notice Burn a Purplecheck token. Must be owner or approved. /// @param tokenId uint256 token ID. function burn(uint256 tokenId) external { address owner = _ownerOf[tokenId]; require( msg.sender == owner || isApprovedForAll[owner][msg.sender] || msg.sender == getApproved[tokenId], "NOT_AUTHORIZED" ); _burn(tokenId); } /// @notice Revert on attempted transfer. function transferFrom(address, address, uint256) public pure override { revert("TRANSFERS_DISABLED"); } /// @notice Withdraw full balance to given recipient address. function withdrawBalance(address to) external onlyOwner { SafeTransferLib.safeTransferETH(to, address(this).balance); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import {unsafeWadDiv} from "solmate/utils/SignedWadMath.sol"; import {VRGDA} from "./VRGDA.sol"; /// @title Linear Variable Rate Gradual Dutch Auction /// @author transmissions11 <[email protected]> /// @author FrankieIsLost <[email protected]> /// @notice VRGDA with a linear issuance curve. abstract contract LinearVRGDA is VRGDA { /*////////////////////////////////////////////////////////////// PRICING PARAMETERS //////////////////////////////////////////////////////////////*/ /// @dev The total number of tokens to target selling every full unit of time. /// @dev Represented as an 18 decimal fixed point number. int256 internal immutable perTimeUnit; /// @notice Sets pricing parameters for the VRGDA. /// @param _targetPrice The target price for a token if sold on pace, scaled by 1e18. /// @param _priceDecayPercent The percent price decays per unit of time with no sales, scaled by 1e18. /// @param _perTimeUnit The number of tokens to target selling in 1 full unit of time, scaled by 1e18. constructor( int256 _targetPrice, int256 _priceDecayPercent, int256 _perTimeUnit ) VRGDA(_targetPrice, _priceDecayPercent) { perTimeUnit = _perTimeUnit; } /*////////////////////////////////////////////////////////////// PRICING LOGIC //////////////////////////////////////////////////////////////*/ /// @dev Given a number of tokens sold, return the target time that number of tokens should be sold by. /// @param sold A number of tokens sold, scaled by 1e18, to get the corresponding target sale time for. /// @return The target time the tokens should be sold by, scaled by 1e18, where the time is /// relative, such that 0 means the tokens should be sold immediately when the VRGDA begins. function getTargetSaleTime(int256 sold) public view virtual override returns (int256) { return unsafeWadDiv(sold, perTimeUnit); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import {wadExp, wadLn, wadMul, unsafeWadMul, toWadUnsafe} from "solmate/utils/SignedWadMath.sol"; /// @title Variable Rate Gradual Dutch Auction /// @author transmissions11 <[email protected]> /// @author FrankieIsLost <[email protected]> /// @notice Sell tokens roughly according to an issuance schedule. abstract contract VRGDA { /*////////////////////////////////////////////////////////////// VRGDA PARAMETERS //////////////////////////////////////////////////////////////*/ /// @notice Target price for a token, to be scaled according to sales pace. /// @dev Represented as an 18 decimal fixed point number. int256 public immutable targetPrice; /// @dev Precomputed constant that allows us to rewrite a pow() as an exp(). /// @dev Represented as an 18 decimal fixed point number. int256 internal immutable decayConstant; /// @notice Sets target price and per time unit price decay for the VRGDA. /// @param _targetPrice The target price for a token if sold on pace, scaled by 1e18. /// @param _priceDecayPercent The percent price decays per unit of time with no sales, scaled by 1e18. constructor(int256 _targetPrice, int256 _priceDecayPercent) { targetPrice = _targetPrice; decayConstant = wadLn(1e18 - _priceDecayPercent); // The decay constant must be negative for VRGDAs to work. require(decayConstant < 0, "NON_NEGATIVE_DECAY_CONSTANT"); } /*////////////////////////////////////////////////////////////// PRICING LOGIC //////////////////////////////////////////////////////////////*/ /// @notice Calculate the price of a token according to the VRGDA formula. /// @param timeSinceStart Time passed since the VRGDA began, scaled by 1e18. /// @param sold The total number of tokens that have been sold so far. /// @return The price of a token according to VRGDA, scaled by 1e18. function getVRGDAPrice(int256 timeSinceStart, uint256 sold) public view virtual returns (uint256) { unchecked { // prettier-ignore return uint256(wadMul(targetPrice, wadExp(unsafeWadMul(decayConstant, // Theoretically calling toWadUnsafe with sold can silently overflow but under // any reasonable circumstance it will never be large enough. We use sold + 1 as // the VRGDA formula's n param represents the nth token and sold is the n-1th token. timeSinceStart - getTargetSaleTime(toWadUnsafe(sold + 1)) )))); } } /// @dev Given a number of tokens sold, return the target time that number of tokens should be sold by. /// @param sold A number of tokens sold, scaled by 1e18, to get the corresponding target sale time for. /// @return The target time the tokens should be sold by, scaled by 1e18, where the time is /// relative, such that 0 means the tokens should be sold immediately when the VRGDA begins. function getTargetSaleTime(int256 sold) public view virtual returns (int256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Library to encode strings in Base64. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/Base64.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Base64.sol) /// @author Modified from (https://github.com/Brechtpd/base64/blob/main/base64.sol) by Brecht Devos - <[email protected]>. library Base64 { /// @dev Encodes `data` using the base64 encoding described in RFC 4648. /// See: https://datatracker.ietf.org/doc/html/rfc4648 /// @param fileSafe Whether to replace '+' with '-' and '/' with '_'. /// @param noPadding Whether to strip away the padding. function encode( bytes memory data, bool fileSafe, bool noPadding ) internal pure returns (string memory result) { assembly { let dataLength := mload(data) if dataLength { // Multiply by 4/3 rounded up. // The `shl(2, ...)` is equivalent to multiplying by 4. let encodedLength := shl(2, div(add(dataLength, 2), 3)) // Set `result` to point to the start of the free memory. result := mload(0x40) // Store the table into the scratch space. // Offsetted by -1 byte so that the `mload` will load the character. // We will rewrite the free memory pointer at `0x40` later with // the allocated size. // The magic constant 0x0230 will translate "-_" + "+/". mstore(0x1f, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef") mstore(0x3f, sub("ghijklmnopqrstuvwxyz0123456789-_", mul(iszero(fileSafe), 0x0230))) // Skip the first slot, which stores the length. let ptr := add(result, 0x20) let end := add(ptr, encodedLength) // Run over the input, 3 bytes at a time. // prettier-ignore for {} 1 {} { data := add(data, 3) // Advance 3 bytes. let input := mload(data) // Write 4 bytes. Optimized for fewer stack operations. mstore8( ptr , mload(and(shr(18, input), 0x3F))) mstore8(add(ptr, 1), mload(and(shr(12, input), 0x3F))) mstore8(add(ptr, 2), mload(and(shr( 6, input), 0x3F))) mstore8(add(ptr, 3), mload(and( input , 0x3F))) ptr := add(ptr, 4) // Advance 4 bytes. // prettier-ignore if iszero(lt(ptr, end)) { break } } let r := mod(dataLength, 3) switch noPadding case 0 { // Offset `ptr` and pad with '='. We can simply write over the end. mstore8(sub(ptr, iszero(iszero(r))), 0x3d) // Pad at `ptr - 1` if `r > 0`. mstore8(sub(ptr, shl(1, eq(r, 1))), 0x3d) // Pad at `ptr - 2` if `r == 1`. // Write the length of the string. mstore(result, encodedLength) } default { // Write the length of the string. mstore(result, sub(encodedLength, add(iszero(iszero(r)), eq(r, 1)))) } // Allocate the memory for the string. // Add 31 and mask with `not(31)` to round the // free memory pointer up the next multiple of 32. mstore(0x40, and(add(end, 31), not(31))) } } } /// @dev Encodes `data` using the base64 encoding described in RFC 4648. /// Equivalent to `encode(data, false, false)`. function encode(bytes memory data) internal pure returns (string memory result) { result = encode(data, false, false); } /// @dev Encodes `data` using the base64 encoding described in RFC 4648. /// Equivalent to `encode(data, fileSafe, false)`. function encode(bytes memory data, bool fileSafe) internal pure returns (string memory result) { result = encode(data, fileSafe, false); } /// @dev Encodes base64 encoded `data`. /// /// Supports: /// - RFC 4648 (both standard and file-safe mode). /// - RFC 3501 (63: ','). /// /// Does not support: /// - Line breaks. /// /// Note: For performance reasons, /// this function will NOT revert on invalid `data` inputs. /// Outputs for invalid inputs will simply be undefined behaviour. /// It is the user's responsibility to ensure that the `data` /// is a valid base64 encoded string. function decode(string memory data) internal pure returns (bytes memory result) { assembly { let dataLength := mload(data) if dataLength { let end := add(data, dataLength) let decodedLength := mul(shr(2, dataLength), 3) switch and(dataLength, 3) case 0 { // If padded. decodedLength := sub( decodedLength, add(eq(and(mload(end), 0xFF), 0x3d), eq(and(mload(end), 0xFFFF), 0x3d3d)) ) } default { // If non-padded. decodedLength := add(decodedLength, sub(and(dataLength, 3), 1)) } result := mload(0x40) // Write the length of the string. mstore(result, decodedLength) // Skip the first slot, which stores the length. let ptr := add(result, 0x20) // Load the table into the scratch space. // Constants are optimized for smaller bytecode with zero gas overhead. // `m` also doubles as the mask of the upper 6 bits. let m := 0xfc000000fc00686c7074787c8084888c9094989ca0a4a8acb0b4b8bcc0c4c8cc mstore(0x5b, m) mstore(0x3b, 0x04080c1014181c2024282c3034383c4044484c5054585c6064) mstore(0x1a, 0xf8fcf800fcd0d4d8dce0e4e8ecf0f4) // prettier-ignore for {} 1 {} { // Read 4 bytes. data := add(data, 4) let input := mload(data) // Write 3 bytes. mstore(ptr, or( and(m, mload(byte(28, input))), shr(6, or( and(m, mload(byte(29, input))), shr(6, or( and(m, mload(byte(30, input))), shr(6, mload(byte(31, input))) )) )) )) ptr := add(ptr, 3) // prettier-ignore if iszero(lt(data, end)) { break } } // Allocate the memory for the string. // Add 32 + 31 and mask with `not(31)` to round the // free memory pointer up the next multiple of 32. mstore(0x40, and(add(add(result, decodedLength), 63), not(31))) // Restore the zero slot. mstore(0x60, 0) } } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Simple single owner authorization mixin. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol) abstract contract Owned { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event OwnershipTransferred(address indexed user, address indexed newOwner); /*////////////////////////////////////////////////////////////// OWNERSHIP STORAGE //////////////////////////////////////////////////////////////*/ address public owner; modifier onlyOwner() virtual { require(msg.sender == owner, "UNAUTHORIZED"); _; } /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(address _owner) { owner = _owner; emit OwnershipTransferred(address(0), _owner); } /*////////////////////////////////////////////////////////////// OWNERSHIP LOGIC //////////////////////////////////////////////////////////////*/ function transferOwnership(address newOwner) public virtual onlyOwner { owner = newOwner; emit OwnershipTransferred(msg.sender, newOwner); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), v, r, s ); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern, minimalist, and gas efficient ERC-721 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) abstract contract ERC721 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 indexed id); event Approval(address indexed owner, address indexed spender, uint256 indexed id); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /*////////////////////////////////////////////////////////////// METADATA STORAGE/LOGIC //////////////////////////////////////////////////////////////*/ string public name; string public symbol; function tokenURI(uint256 id) public view virtual returns (string memory); /*////////////////////////////////////////////////////////////// ERC721 BALANCE/OWNER STORAGE //////////////////////////////////////////////////////////////*/ mapping(uint256 => address) internal _ownerOf; mapping(address => uint256) internal _balanceOf; function ownerOf(uint256 id) public view virtual returns (address owner) { require((owner = _ownerOf[id]) != address(0), "NOT_MINTED"); } function balanceOf(address owner) public view virtual returns (uint256) { require(owner != address(0), "ZERO_ADDRESS"); return _balanceOf[owner]; } /*////////////////////////////////////////////////////////////// ERC721 APPROVAL STORAGE //////////////////////////////////////////////////////////////*/ mapping(uint256 => address) public getApproved; mapping(address => mapping(address => bool)) public isApprovedForAll; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(string memory _name, string memory _symbol) { name = _name; symbol = _symbol; } /*////////////////////////////////////////////////////////////// ERC721 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 id) public virtual { address owner = _ownerOf[id]; require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED"); getApproved[id] = spender; emit Approval(owner, spender, id); } function setApprovalForAll(address operator, bool approved) public virtual { isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function transferFrom( address from, address to, uint256 id ) public virtual { require(from == _ownerOf[id], "WRONG_FROM"); require(to != address(0), "INVALID_RECIPIENT"); require( msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id], "NOT_AUTHORIZED" ); // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. unchecked { _balanceOf[from]--; _balanceOf[to]++; } _ownerOf[id] = to; delete getApproved[id]; emit Transfer(from, to, id); } function safeTransferFrom( address from, address to, uint256 id ) public virtual { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function safeTransferFrom( address from, address to, uint256 id, bytes calldata data ) public virtual { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } /*////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721 interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 id) internal virtual { require(to != address(0), "INVALID_RECIPIENT"); require(_ownerOf[id] == address(0), "ALREADY_MINTED"); // Counter overflow is incredibly unrealistic. unchecked { _balanceOf[to]++; } _ownerOf[id] = to; emit Transfer(address(0), to, id); } function _burn(uint256 id) internal virtual { address owner = _ownerOf[id]; require(owner != address(0), "NOT_MINTED"); // Ownership check above ensures no underflow. unchecked { _balanceOf[owner]--; } delete _ownerOf[id]; delete getApproved[id]; emit Transfer(owner, address(0), id); } /*////////////////////////////////////////////////////////////// INTERNAL SAFE MINT LOGIC //////////////////////////////////////////////////////////////*/ function _safeMint(address to, uint256 id) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function _safeMint( address to, uint256 id, bytes memory data ) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } } /// @notice A generic interface for a contract which properly accepts ERC721 tokens. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) abstract contract ERC721TokenReceiver { function onERC721Received( address, address, uint256, bytes calldata ) external virtual returns (bytes4) { return ERC721TokenReceiver.onERC721Received.selector; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; /// @notice Efficient library for creating string representations of integers. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol) /// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibString.sol) library LibString { function toString(uint256 value) internal pure returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but we allocate 160 bytes // to keep the free memory pointer word aligned. We'll need 1 word for the length, 1 word for the // trailing zeros padding, and 3 other words for a max of 78 digits. In total: 5 * 32 = 160 bytes. let newFreeMemoryPointer := add(mload(0x40), 160) // Update the free memory pointer to avoid overriding our string. mstore(0x40, newFreeMemoryPointer) // Assign str to the end of the zone of newly allocated memory. str := sub(newFreeMemoryPointer, 32) // Clean the last word of memory it may not be overwritten. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { // Move the pointer 1 byte to the left. str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing temp until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } // Compute and cache the final total length of the string. let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 32) // Store the string's length at the start of memory allocated for our string. mstore(str, length) } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; import {ERC20} from "../tokens/ERC20.sol"; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. /// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller. library SafeTransferLib { /*////////////////////////////////////////////////////////////// ETH OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferETH(address to, uint256 amount) internal { bool success; assembly { // Transfer the ETH and store if it succeeded or not. success := call(gas(), to, amount, 0, 0, 0, 0) } require(success, "ETH_TRANSFER_FAILED"); } /*////////////////////////////////////////////////////////////// ERC20 OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferFrom( ERC20 token, address from, address to, uint256 amount ) internal { bool success; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument. mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 100, 0, 32) ) } require(success, "TRANSFER_FROM_FAILED"); } function safeTransfer( ERC20 token, address to, uint256 amount ) internal { bool success; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "TRANSFER_FAILED"); } function safeApprove( ERC20 token, address to, uint256 amount ) internal { bool success; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "APPROVE_FAILED"); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; /// @notice Signed 18 decimal fixed point (wad) arithmetic library. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SignedWadMath.sol) /// @author Modified from Remco Bloemen (https://xn--2-umb.com/22/exp-ln/index.html) /// @dev Will not revert on overflow, only use where overflow is not possible. function toWadUnsafe(uint256 x) pure returns (int256 r) { assembly { // Multiply x by 1e18. r := mul(x, 1000000000000000000) } } /// @dev Takes an integer amount of seconds and converts it to a wad amount of days. /// @dev Will not revert on overflow, only use where overflow is not possible. /// @dev Not meant for negative second amounts, it assumes x is positive. function toDaysWadUnsafe(uint256 x) pure returns (int256 r) { assembly { // Multiply x by 1e18 and then divide it by 86400. r := div(mul(x, 1000000000000000000), 86400) } } /// @dev Takes a wad amount of days and converts it to an integer amount of seconds. /// @dev Will not revert on overflow, only use where overflow is not possible. /// @dev Not meant for negative day amounts, it assumes x is positive. function fromDaysWadUnsafe(int256 x) pure returns (uint256 r) { assembly { // Multiply x by 86400 and then divide it by 1e18. r := div(mul(x, 86400), 1000000000000000000) } } /// @dev Will not revert on overflow, only use where overflow is not possible. function unsafeWadMul(int256 x, int256 y) pure returns (int256 r) { assembly { // Multiply x by y and divide by 1e18. r := sdiv(mul(x, y), 1000000000000000000) } } /// @dev Will return 0 instead of reverting if y is zero and will /// not revert on overflow, only use where overflow is not possible. function unsafeWadDiv(int256 x, int256 y) pure returns (int256 r) { assembly { // Multiply x by 1e18 and divide it by y. r := sdiv(mul(x, 1000000000000000000), y) } } function wadMul(int256 x, int256 y) pure returns (int256 r) { assembly { // Store x * y in r for now. r := mul(x, y) // Equivalent to require(x == 0 || (x * y) / x == y) if iszero(or(iszero(x), eq(sdiv(r, x), y))) { revert(0, 0) } // Scale the result down by 1e18. r := sdiv(r, 1000000000000000000) } } function wadDiv(int256 x, int256 y) pure returns (int256 r) { assembly { // Store x * 1e18 in r for now. r := mul(x, 1000000000000000000) // Equivalent to require(y != 0 && ((x * 1e18) / 1e18 == x)) if iszero(and(iszero(iszero(y)), eq(sdiv(r, 1000000000000000000), x))) { revert(0, 0) } // Divide r by y. r := sdiv(r, y) } } function wadExp(int256 x) pure returns (int256 r) { unchecked { // When the result is < 0.5 we return zero. This happens when // x <= floor(log(0.5e18) * 1e18) ~ -42e18 if (x <= -42139678854452767551) return 0; // When the result is > (2**255 - 1) / 1e18 we can not represent it as an // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135. if (x >= 135305999368893231589) revert("EXP_OVERFLOW"); // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96 // for more intermediate precision and a binary basis. This base conversion // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78. x = (x << 78) / 5**18; // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers // of two such that exp(x) = exp(x') * 2**k, where k is an integer. // Solving this gives k = round(x / log(2)) and x' = x - k * log(2). int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96; x = x - k * 54916777467707473351141471128; // k is in the range [-61, 195]. // Evaluate using a (6, 7)-term rational approximation. // p is made monic, we'll multiply by a scale factor later. int256 y = x + 1346386616545796478920950773328; y = ((y * x) >> 96) + 57155421227552351082224309758442; int256 p = y + x - 94201549194550492254356042504812; p = ((p * y) >> 96) + 28719021644029726153956944680412240; p = p * x + (4385272521454847904659076985693276 << 96); // We leave p in 2**192 basis so we don't need to scale it back up for the division. int256 q = x - 2855989394907223263936484059900; q = ((q * x) >> 96) + 50020603652535783019961831881945; q = ((q * x) >> 96) - 533845033583426703283633433725380; q = ((q * x) >> 96) + 3604857256930695427073651918091429; q = ((q * x) >> 96) - 14423608567350463180887372962807573; q = ((q * x) >> 96) + 26449188498355588339934803723976023; assembly { // Div in assembly because solidity adds a zero check despite the unchecked. // The q polynomial won't have zeros in the domain as all its roots are complex. // No scaling is necessary because p is already 2**96 too large. r := sdiv(p, q) } // r should be in the range (0.09, 0.25) * 2**96. // We now need to multiply r by: // * the scale factor s = ~6.031367120. // * the 2**k factor from the range reduction. // * the 1e18 / 2**96 factor for base conversion. // We do this all at once, with an intermediate result in 2**213 // basis, so the final right shift is always by a positive amount. r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k)); } } function wadLn(int256 x) pure returns (int256 r) { unchecked { require(x > 0, "UNDEFINED"); // We want to convert x from 10**18 fixed point to 2**96 fixed point. // We do this by multiplying by 2**96 / 10**18. But since // ln(x * C) = ln(x) + ln(C), we can simply do nothing here // and add ln(2**96 / 10**18) at the end. assembly { r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) r := or(r, shl(4, lt(0xffff, shr(r, x)))) r := or(r, shl(3, lt(0xff, shr(r, x)))) r := or(r, shl(2, lt(0xf, shr(r, x)))) r := or(r, shl(1, lt(0x3, shr(r, x)))) r := or(r, lt(0x1, shr(r, x))) } // Reduce range of x to (1, 2) * 2**96 // ln(2^k * x) = k * ln(2) + ln(x) int256 k = r - 96; x <<= uint256(159 - k); x = int256(uint256(x) >> 159); // Evaluate using a (8, 8)-term rational approximation. // p is made monic, we will multiply by a scale factor later. int256 p = x + 3273285459638523848632254066296; p = ((p * x) >> 96) + 24828157081833163892658089445524; p = ((p * x) >> 96) + 43456485725739037958740375743393; p = ((p * x) >> 96) - 11111509109440967052023855526967; p = ((p * x) >> 96) - 45023709667254063763336534515857; p = ((p * x) >> 96) - 14706773417378608786704636184526; p = p * x - (795164235651350426258249787498 << 96); // We leave p in 2**192 basis so we don't need to scale it back up for the division. // q is monic by convention. int256 q = x + 5573035233440673466300451813936; q = ((q * x) >> 96) + 71694874799317883764090561454958; q = ((q * x) >> 96) + 283447036172924575727196451306956; q = ((q * x) >> 96) + 401686690394027663651624208769553; q = ((q * x) >> 96) + 204048457590392012362485061816622; q = ((q * x) >> 96) + 31853899698501571402653359427138; q = ((q * x) >> 96) + 909429971244387300277376558375; assembly { // Div in assembly because solidity adds a zero check despite the unchecked. // The q polynomial is known not to have zeros in the domain. // No scaling required because p is already 2**96 too large. r := sdiv(p, q) } // r is in the range (0, 0.125) * 2**96 // Finalization, we need to: // * multiply by the scale factor s = 5.549… // * add ln(2**96 / 10**18) // * add k * ln(2) // * multiply by 10**18 / 2**96 = 5**18 >> 78 // mul s * 5e18 * 2**96, base is now 5**18 * 2**192 r *= 1677202110996718588342820967067443963516166; // add ln(2) * k * 5e18 * 2**192 r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k; // add ln(2**96 / 10**18) * 5e18 * 2**192 r += 600920179829731861736702779321621459595472258049074101567377883020018308; // base conversion: mul 2**18 / 2**192 r >>= 174; } } /// @dev Will return 0 instead of reverting if y is zero. function unsafeDiv(int256 x, int256 y) pure returns (int256 r) { assembly { // Divide x by y. r := sdiv(x, y) } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; import {LibString} from "solmate/utils/LibString.sol"; import {Base64} from "solady/utils/Base64.sol"; library Metadata { using LibString for uint256; function toImageURI(string memory cid) internal pure returns (string memory) { return string.concat("ipfs://", cid); } function tokenJSON(uint256 tokenId, string memory imageURI) internal pure returns (string memory) { return string.concat('{"image":"', imageURI, '","name":"Purplecheck #', tokenId.toString(), '"}'); } function contractJSON() internal pure returns (string memory) { return '{"name":"Purplecheck","image":"ipfs://bafkreibhw7wybdzmpg5tfjr6pjynalpeb3zs7c3va26prjyc6gl2bvo7y4","description":"Your JPEGs deserve to feel special."}'; } function contractURI() internal pure returns (string memory) { return toDataURI(contractJSON()); } function tokenURI(uint256 tokenId, string memory imageURI) internal pure returns (string memory) { return toDataURI(tokenJSON(tokenId, imageURI)); } function toDataURI(string memory json) internal pure returns (string memory) { return string.concat("data:application/json;base64,", Base64.encode(abi.encodePacked(json))); } }
{ "remappings": [ "VRGDAs/=lib/VRGDAs/src/", "ds-test/=lib/VRGDAs/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "solady/=lib/solady/src/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 200000 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","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":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"cid","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"sold","type":"int256"}],"name":"getTargetSaleTime","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"timeSinceStart","type":"int256"},{"internalType":"uint256","name":"sold","type":"uint256"}],"name":"getVRGDAPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"imageURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_cid","type":"string"}],"name":"mint","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","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":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","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":"id","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":"id","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":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"targetPrice","outputs":[{"internalType":"int256","name":"","type":"int256"}],"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":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"withdrawBalance","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101006040524260e0523480156200001657600080fd5b506040516200286d3803806200286d8339810160408190526200003991620003be565b80660eebe0b40e800067044d575b885f0000675fc1b9713632000082826040518060400160405280600b81526020016a507572706c65636865636b60a81b8152506040518060400160405280600a815260200169f09f9faaefb88fe29c8560b01b8152508160009081620000ae919062000495565b506001620000bd828262000495565b5050506080829052620000e3620000dd82670de0b6b3a764000062000561565b62000195565b60a08190526000136200013d5760405162461bcd60e51b815260206004820152601b60248201527f4e4f4e5f4e454741544956455f44454341595f434f4e5354414e54000000000060448201526064015b60405180910390fd5b505060c0525050600680546001600160a01b0319166001600160a01b0383169081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3505062000597565b6000808213620001d45760405162461bcd60e51b815260206004820152600960248201526815539111519253915160ba1b604482015260640162000134565b5060606001600160801b03821160071b82811c6001600160401b031060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110600190811b90911783811c90911017609f81810383019390931b90921c6c465772b2bbbb5f824b15207a3081018102821d6d0388eaa27412d5aca026815d636e018102821d6d0df99ac502031bf953eff472fdcc018102821d6d13cdffb29d51d99322bdff5f2211018102821d6d0a0f742023def783a307a986912e018102821d6d01920d8043ca89b5239253284e42018102821d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7882018202831d6d0139601a2efabe717e604cbb4894018202831d6d02247f7a7b6594320649aa03aba1018202831d6c8c3f38e95a6b1ff2ab1c3b343619018202831d6d02384773bdf1ac5676facced60901901820290921d6cb9a025d814b29c212b8b1a07cd19010260016c0504a838426634cdd8738f543560611b03190105711340daa0d5f769dba1915cef59f0815a550602605f19919091017d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b600060208284031215620003d157600080fd5b81516001600160a01b0381168114620003e957600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200041b57607f821691505b6020821081036200043c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200049057600081815260208120601f850160051c810160208610156200046b5750805b601f850160051c820191505b818110156200048c5782815560010162000477565b5050505b505050565b81516001600160401b03811115620004b157620004b1620003f0565b620004c981620004c2845462000406565b8462000442565b602080601f831160018114620005015760008415620004e85750858301515b600019600386901b1c1916600185901b1785556200048c565b600085815260208120601f198616915b82811015620005325788860151825594840194600190910190840162000511565b5085821015620005515787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b81810360008312801583831316838312821617156200059057634e487b7160e01b600052601160045260246000fd5b5092915050565b60805160a05160c05160e05161228e620005df600039600081816103a80152610de201526000610bbf015260006112340152600081816104e6015261120d015261228e6000f3fe6080604052600436106101ac5760003560e01c80638da5cb5b116100ec578063c87b56dd1161008a578063e8a3d48511610064578063e8a3d48514610508578063e985e9c51461051d578063f2fde38b14610558578063f466d4ab1461057857600080fd5b8063c87b56dd146104a1578063d85d3d27146104c1578063dc38679c146104d457600080fd5b8063a035b1fe116100c6578063a035b1fe1461042c578063a22cb46514610441578063b0c479a514610461578063b88d4fde1461048157600080fd5b80638da5cb5b146103ca5780638f742d16146103f757806395d89b411461041757600080fd5b806342842e0e116101595780636d9d33b7116101335780636d9d33b71461033657806370a0823114610356578063756af45f1461037657806378e979251461039657600080fd5b806342842e0e146102d657806342966c68146102f65780636352211e1461031657600080fd5b8063095ea7b31161018a578063095ea7b31461027057806318160ddd1461029257806323b872dd146102b657600080fd5b806301ffc9a7146101b157806306fdde03146101e6578063081812fc14610208575b600080fd5b3480156101bd57600080fd5b506101d16101cc366004611ad5565b610598565b60405190151581526020015b60405180910390f35b3480156101f257600080fd5b506101fb61067d565b6040516101dd9190611b16565b34801561021457600080fd5b5061024b610223366004611b67565b60046020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101dd565b34801561027c57600080fd5b5061029061028b366004611ba4565b61070b565b005b34801561029e57600080fd5b506102a860075481565b6040519081526020016101dd565b3480156102c257600080fd5b506102906102d1366004611bce565b61085a565b3480156102e257600080fd5b506102906102f1366004611bce565b6108bc565b34801561030257600080fd5b50610290610311366004611b67565b610a26565b34801561032257600080fd5b5061024b610331366004611b67565b610b2a565b34801561034257600080fd5b506102a8610351366004611b67565b610bbb565b34801561036257600080fd5b506102a8610371366004611c0a565b610bef565b34801561038257600080fd5b50610290610391366004611c0a565b610c97565b3480156103a257600080fd5b506102a87f000000000000000000000000000000000000000000000000000000000000000081565b3480156103d657600080fd5b5060065461024b9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561040357600080fd5b506101fb610412366004611b67565b610d25565b34801561042357600080fd5b506101fb610dc8565b34801561043857600080fd5b506102a8610dd5565b34801561044d57600080fd5b5061029061045c366004611c25565b610e29565b34801561046d57600080fd5b506101fb61047c366004611b67565b610ec0565b34801561048d57600080fd5b5061029061049c366004611caa565b610ed9565b3480156104ad57600080fd5b506101fb6104bc366004611b67565b611033565b6102a86104cf366004611d19565b611047565b3480156104e057600080fd5b506102a87f000000000000000000000000000000000000000000000000000000000000000081565b34801561051457600080fd5b506101fb61110a565b34801561052957600080fd5b506101d1610538366004611d5b565b600560209081526000928352604080842090915290825290205460ff1681565b34801561056457600080fd5b50610290610573366004611c0a565b611114565b34801561058457600080fd5b506102a8610593366004611d8e565b611206565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061062b57507f80ac58cd000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b8061067757507f5b5e139f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6000805461068a90611db0565b80601f01602080910402602001604051908101604052809291908181526020018280546106b690611db0565b80156107035780601f106106d857610100808354040283529160200191610703565b820191906000526020600020905b8154815290600101906020018083116106e657829003601f168201915b505050505081565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff163381148061076e575073ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152604080832033845290915290205460ff165b6107d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008281526004602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f5452414e53464552535f44495341424c4544000000000000000000000000000060448201526064016107d0565b6108c783838361085a565b73ffffffffffffffffffffffffffffffffffffffff82163b15806109bb57506040517f150b7a020000000000000000000000000000000000000000000000000000000080825233600483015273ffffffffffffffffffffffffffffffffffffffff858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af1158015610973573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109979190611e03565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b610a21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e540000000000000000000000000000000060448201526064016107d0565b505050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1633811480610a89575073ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152604080832033845290915290205460ff165b80610ab7575060008281526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1633145b610b1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016107d0565b610b268261128b565b5050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610bb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f4d494e5445440000000000000000000000000000000000000000000060448201526064016107d0565b919050565b60007f0000000000000000000000000000000000000000000000000000000000000000670de0b6b3a7640000830205610677565b600073ffffffffffffffffffffffffffffffffffffffff8216610c6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5a45524f5f41444452455353000000000000000000000000000000000000000060448201526064016107d0565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b60065473ffffffffffffffffffffffffffffffffffffffff163314610d18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016107d0565b610d2281476113d5565b50565b6000818152600860205260409020805460609161067791610d4590611db0565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7190611db0565b8015610dbe5780601f10610d9357610100808354040283529160200191610dbe565b820191906000526020600020905b815481529060010190602001808311610da157829003601f168201915b505050505061144a565b6001805461068a90611db0565b6000610e24610e1c610e077f000000000000000000000000000000000000000000000000000000000000000042611e20565b62015180670de0b6b3a7640000919091020490565b600754611206565b905090565b33600081815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6008602052600090815260409020805461068a90611db0565b610ee485858561085a565b73ffffffffffffffffffffffffffffffffffffffff84163b1580610fc657506040517f150b7a02000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff86169063150b7a0290610f5f9033908a90899089908990600401611e5a565b6020604051808303816000875af1158015610f7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa29190611e03565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b61102c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e540000000000000000000000000000000060448201526064016107d0565b5050505050565b60606106778261104284610d25565b611473565b600080611052610dd5565b9050803410156110be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e44455250414944000000000000000000000000000000000000000000000060448201526064016107d0565b600780546001019081905560008181526008602052604090209092506110e5848683611f56565b506110f03383611487565b80341461110357611103338234036113d5565b5092915050565b6060610e24611620565b60065473ffffffffffffffffffffffffffffffffffffffff163314611195576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016107d0565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831690811790915560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b60006112847f000000000000000000000000000000000000000000000000000000000000000061127f61127a7f0000000000000000000000000000000000000000000000000000000000000000611269670de0b6b3a76400006001890102610bbb565b8803670de0b6b3a764000091020590565b61162d565b61186c565b9392505050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1680611317576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f4d494e5445440000000000000000000000000000000000000000000060448201526064016107d0565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260036020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190558583526002825280832080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811690915560049092528083208054909216909155518492907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600080600080600085875af1905080610a21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c45440000000000000000000000000060448201526064016107d0565b60608160405160200161145d9190612070565b6040516020818303038152906040529050919050565b60606112846114828484611891565b6118c5565b73ffffffffffffffffffffffffffffffffffffffff8216611504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f524543495049454e5400000000000000000000000000000060448201526064016107d0565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f414c52454144595f4d494e54454400000000000000000000000000000000000060448201526064016107d0565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260036020908152604080832080546001019055848352600290915280822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6060610e246114826118ff565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361165e57506000919050565b680755bf798b4a1bf1e582126116d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f57000000000000000000000000000000000000000060448201526064016107d0565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b818102821583820583141761188057600080fd5b670de0b6b3a7640000900592915050565b60608161189d8461191f565b6040516020016118ae9291906120b5565b604051602081830303815290604052905092915050565b60606118ef826040516020016118db9190612160565b604051602081830303815290604052611981565b60405160200161145d919061217c565b60606040518060c00160405280609781526020016121c260979139905090565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a90048061193957508190037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909101908152919050565b606061067782600080606083518015611a9f576003600282010460021b60405192507f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f526102308515027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f03603f52602083018181015b6003880197508751603f8160121c16518353603f81600c1c16516001840153603f8160061c16516002840153603f8116516003840153506004820191508082106119fa5760038406868015611a5a57600182148215150185038752611a72565b603d821515850353603d6001831460011b8503538487525b5050601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660405250505b509392505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114610d2257600080fd5b600060208284031215611ae757600080fd5b813561128481611aa7565b60005b83811015611b0d578181015183820152602001611af5565b50506000910152565b6020815260008251806020840152611b35816040850160208701611af2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600060208284031215611b7957600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610bb657600080fd5b60008060408385031215611bb757600080fd5b611bc083611b80565b946020939093013593505050565b600080600060608486031215611be357600080fd5b611bec84611b80565b9250611bfa60208501611b80565b9150604084013590509250925092565b600060208284031215611c1c57600080fd5b61128482611b80565b60008060408385031215611c3857600080fd5b611c4183611b80565b915060208301358015158114611c5657600080fd5b809150509250929050565b60008083601f840112611c7357600080fd5b50813567ffffffffffffffff811115611c8b57600080fd5b602083019150836020828501011115611ca357600080fd5b9250929050565b600080600080600060808688031215611cc257600080fd5b611ccb86611b80565b9450611cd960208701611b80565b935060408601359250606086013567ffffffffffffffff811115611cfc57600080fd5b611d0888828901611c61565b969995985093965092949392505050565b60008060208385031215611d2c57600080fd5b823567ffffffffffffffff811115611d4357600080fd5b611d4f85828601611c61565b90969095509350505050565b60008060408385031215611d6e57600080fd5b611d7783611b80565b9150611d8560208401611b80565b90509250929050565b60008060408385031215611da157600080fd5b50508035926020909101359150565b600181811c90821680611dc457607f821691505b602082108103611dfd577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215611e1557600080fd5b815161128481611aa7565b81810381811115610677577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011683010190509695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b601f821115610a2157600081815260208120601f850160051c81016020861015611f2f5750805b601f850160051c820191505b81811015611f4e57828155600101611f3b565b505050505050565b67ffffffffffffffff831115611f6e57611f6e611ed9565b611f8283611f7c8354611db0565b83611f08565b6000601f841160018114611fd45760008515611f9e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561102c565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156120235786850135825560209485019460019092019101612003565b508682101561205e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b7f697066733a2f2f000000000000000000000000000000000000000000000000008152600082516120a8816007850160208701611af2565b9190910160070192915050565b7f7b22696d616765223a22000000000000000000000000000000000000000000008152600083516120ed81600a850160208801611af2565b7f222c226e616d65223a22507572706c65636865636b2023000000000000000000600a91840191820152835161212a816021840160208801611af2565b7f227d00000000000000000000000000000000000000000000000000000000000060219290910191820152602301949350505050565b60008251612172818460208701611af2565b9190910192915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008152600082516121b481601d850160208701611af2565b91909101601d019291505056fe7b226e616d65223a22507572706c65636865636b222c22696d616765223a22697066733a2f2f6261666b72656962687737777962647a6d70673574666a7236706a796e616c706562337a733763337661323670726a796336676c3262766f377934222c226465736372697074696f6e223a22596f7572204a50454773206465736572766520746f206665656c207370656369616c2e227da2646970667358221220668d48eb1f816d1ddc35de38ea2b4a14824c6087bb99575fea2489c30fe5a5c264736f6c6343000810003300000000000000000000000079d31bfca5fda7a4f15b36763d2e44c99d811a6c
Deployed Bytecode
0x6080604052600436106101ac5760003560e01c80638da5cb5b116100ec578063c87b56dd1161008a578063e8a3d48511610064578063e8a3d48514610508578063e985e9c51461051d578063f2fde38b14610558578063f466d4ab1461057857600080fd5b8063c87b56dd146104a1578063d85d3d27146104c1578063dc38679c146104d457600080fd5b8063a035b1fe116100c6578063a035b1fe1461042c578063a22cb46514610441578063b0c479a514610461578063b88d4fde1461048157600080fd5b80638da5cb5b146103ca5780638f742d16146103f757806395d89b411461041757600080fd5b806342842e0e116101595780636d9d33b7116101335780636d9d33b71461033657806370a0823114610356578063756af45f1461037657806378e979251461039657600080fd5b806342842e0e146102d657806342966c68146102f65780636352211e1461031657600080fd5b8063095ea7b31161018a578063095ea7b31461027057806318160ddd1461029257806323b872dd146102b657600080fd5b806301ffc9a7146101b157806306fdde03146101e6578063081812fc14610208575b600080fd5b3480156101bd57600080fd5b506101d16101cc366004611ad5565b610598565b60405190151581526020015b60405180910390f35b3480156101f257600080fd5b506101fb61067d565b6040516101dd9190611b16565b34801561021457600080fd5b5061024b610223366004611b67565b60046020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101dd565b34801561027c57600080fd5b5061029061028b366004611ba4565b61070b565b005b34801561029e57600080fd5b506102a860075481565b6040519081526020016101dd565b3480156102c257600080fd5b506102906102d1366004611bce565b61085a565b3480156102e257600080fd5b506102906102f1366004611bce565b6108bc565b34801561030257600080fd5b50610290610311366004611b67565b610a26565b34801561032257600080fd5b5061024b610331366004611b67565b610b2a565b34801561034257600080fd5b506102a8610351366004611b67565b610bbb565b34801561036257600080fd5b506102a8610371366004611c0a565b610bef565b34801561038257600080fd5b50610290610391366004611c0a565b610c97565b3480156103a257600080fd5b506102a87f00000000000000000000000000000000000000000000000000000000634f87f781565b3480156103d657600080fd5b5060065461024b9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561040357600080fd5b506101fb610412366004611b67565b610d25565b34801561042357600080fd5b506101fb610dc8565b34801561043857600080fd5b506102a8610dd5565b34801561044d57600080fd5b5061029061045c366004611c25565b610e29565b34801561046d57600080fd5b506101fb61047c366004611b67565b610ec0565b34801561048d57600080fd5b5061029061049c366004611caa565b610ed9565b3480156104ad57600080fd5b506101fb6104bc366004611b67565b611033565b6102a86104cf366004611d19565b611047565b3480156104e057600080fd5b506102a87f000000000000000000000000000000000000000000000000000eebe0b40e800081565b34801561051457600080fd5b506101fb61110a565b34801561052957600080fd5b506101d1610538366004611d5b565b600560209081526000928352604080842090915290825290205460ff1681565b34801561056457600080fd5b50610290610573366004611c0a565b611114565b34801561058457600080fd5b506102a8610593366004611d8e565b611206565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061062b57507f80ac58cd000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b8061067757507f5b5e139f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6000805461068a90611db0565b80601f01602080910402602001604051908101604052809291908181526020018280546106b690611db0565b80156107035780601f106106d857610100808354040283529160200191610703565b820191906000526020600020905b8154815290600101906020018083116106e657829003601f168201915b505050505081565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff163381148061076e575073ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152604080832033845290915290205460ff165b6107d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008281526004602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f5452414e53464552535f44495341424c4544000000000000000000000000000060448201526064016107d0565b6108c783838361085a565b73ffffffffffffffffffffffffffffffffffffffff82163b15806109bb57506040517f150b7a020000000000000000000000000000000000000000000000000000000080825233600483015273ffffffffffffffffffffffffffffffffffffffff858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af1158015610973573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109979190611e03565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b610a21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e540000000000000000000000000000000060448201526064016107d0565b505050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1633811480610a89575073ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152604080832033845290915290205460ff165b80610ab7575060008281526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1633145b610b1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016107d0565b610b268261128b565b5050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610bb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f4d494e5445440000000000000000000000000000000000000000000060448201526064016107d0565b919050565b60007f0000000000000000000000000000000000000000000000005fc1b97136320000670de0b6b3a7640000830205610677565b600073ffffffffffffffffffffffffffffffffffffffff8216610c6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5a45524f5f41444452455353000000000000000000000000000000000000000060448201526064016107d0565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b60065473ffffffffffffffffffffffffffffffffffffffff163314610d18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016107d0565b610d2281476113d5565b50565b6000818152600860205260409020805460609161067791610d4590611db0565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7190611db0565b8015610dbe5780601f10610d9357610100808354040283529160200191610dbe565b820191906000526020600020905b815481529060010190602001808311610da157829003601f168201915b505050505061144a565b6001805461068a90611db0565b6000610e24610e1c610e077f00000000000000000000000000000000000000000000000000000000634f87f742611e20565b62015180670de0b6b3a7640000919091020490565b600754611206565b905090565b33600081815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6008602052600090815260409020805461068a90611db0565b610ee485858561085a565b73ffffffffffffffffffffffffffffffffffffffff84163b1580610fc657506040517f150b7a02000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff86169063150b7a0290610f5f9033908a90899089908990600401611e5a565b6020604051808303816000875af1158015610f7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa29190611e03565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b61102c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e540000000000000000000000000000000060448201526064016107d0565b5050505050565b60606106778261104284610d25565b611473565b600080611052610dd5565b9050803410156110be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e44455250414944000000000000000000000000000000000000000000000060448201526064016107d0565b600780546001019081905560008181526008602052604090209092506110e5848683611f56565b506110f03383611487565b80341461110357611103338234036113d5565b5092915050565b6060610e24611620565b60065473ffffffffffffffffffffffffffffffffffffffff163314611195576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016107d0565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831690811790915560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b60006112847f000000000000000000000000000000000000000000000000000eebe0b40e800061127f61127a7ffffffffffffffffffffffffffffffffffffffffffffffffffad9b78c39a6968e611269670de0b6b3a76400006001890102610bbb565b8803670de0b6b3a764000091020590565b61162d565b61186c565b9392505050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1680611317576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f4d494e5445440000000000000000000000000000000000000000000060448201526064016107d0565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260036020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190558583526002825280832080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811690915560049092528083208054909216909155518492907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600080600080600085875af1905080610a21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c45440000000000000000000000000060448201526064016107d0565b60608160405160200161145d9190612070565b6040516020818303038152906040529050919050565b60606112846114828484611891565b6118c5565b73ffffffffffffffffffffffffffffffffffffffff8216611504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f524543495049454e5400000000000000000000000000000060448201526064016107d0565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f414c52454144595f4d494e54454400000000000000000000000000000000000060448201526064016107d0565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260036020908152604080832080546001019055848352600290915280822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6060610e246114826118ff565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361165e57506000919050565b680755bf798b4a1bf1e582126116d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f57000000000000000000000000000000000000000060448201526064016107d0565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b818102821583820583141761188057600080fd5b670de0b6b3a7640000900592915050565b60608161189d8461191f565b6040516020016118ae9291906120b5565b604051602081830303815290604052905092915050565b60606118ef826040516020016118db9190612160565b604051602081830303815290604052611981565b60405160200161145d919061217c565b60606040518060c00160405280609781526020016121c260979139905090565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a90048061193957508190037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909101908152919050565b606061067782600080606083518015611a9f576003600282010460021b60405192507f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f526102308515027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f03603f52602083018181015b6003880197508751603f8160121c16518353603f81600c1c16516001840153603f8160061c16516002840153603f8116516003840153506004820191508082106119fa5760038406868015611a5a57600182148215150185038752611a72565b603d821515850353603d6001831460011b8503538487525b5050601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660405250505b509392505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114610d2257600080fd5b600060208284031215611ae757600080fd5b813561128481611aa7565b60005b83811015611b0d578181015183820152602001611af5565b50506000910152565b6020815260008251806020840152611b35816040850160208701611af2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600060208284031215611b7957600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610bb657600080fd5b60008060408385031215611bb757600080fd5b611bc083611b80565b946020939093013593505050565b600080600060608486031215611be357600080fd5b611bec84611b80565b9250611bfa60208501611b80565b9150604084013590509250925092565b600060208284031215611c1c57600080fd5b61128482611b80565b60008060408385031215611c3857600080fd5b611c4183611b80565b915060208301358015158114611c5657600080fd5b809150509250929050565b60008083601f840112611c7357600080fd5b50813567ffffffffffffffff811115611c8b57600080fd5b602083019150836020828501011115611ca357600080fd5b9250929050565b600080600080600060808688031215611cc257600080fd5b611ccb86611b80565b9450611cd960208701611b80565b935060408601359250606086013567ffffffffffffffff811115611cfc57600080fd5b611d0888828901611c61565b969995985093965092949392505050565b60008060208385031215611d2c57600080fd5b823567ffffffffffffffff811115611d4357600080fd5b611d4f85828601611c61565b90969095509350505050565b60008060408385031215611d6e57600080fd5b611d7783611b80565b9150611d8560208401611b80565b90509250929050565b60008060408385031215611da157600080fd5b50508035926020909101359150565b600181811c90821680611dc457607f821691505b602082108103611dfd577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215611e1557600080fd5b815161128481611aa7565b81810381811115610677577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011683010190509695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b601f821115610a2157600081815260208120601f850160051c81016020861015611f2f5750805b601f850160051c820191505b81811015611f4e57828155600101611f3b565b505050505050565b67ffffffffffffffff831115611f6e57611f6e611ed9565b611f8283611f7c8354611db0565b83611f08565b6000601f841160018114611fd45760008515611f9e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561102c565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156120235786850135825560209485019460019092019101612003565b508682101561205e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b7f697066733a2f2f000000000000000000000000000000000000000000000000008152600082516120a8816007850160208701611af2565b9190910160070192915050565b7f7b22696d616765223a22000000000000000000000000000000000000000000008152600083516120ed81600a850160208801611af2565b7f222c226e616d65223a22507572706c65636865636b2023000000000000000000600a91840191820152835161212a816021840160208801611af2565b7f227d00000000000000000000000000000000000000000000000000000000000060219290910191820152602301949350505050565b60008251612172818460208701611af2565b9190910192915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008152600082516121b481601d850160208701611af2565b91909101601d019291505056fe7b226e616d65223a22507572706c65636865636b222c22696d616765223a22697066733a2f2f6261666b72656962687737777962647a6d70673574666a7236706a796e616c706562337a733763337661323670726a796336676c3262766f377934222c226465736372697074696f6e223a22596f7572204a50454773206465736572766520746f206665656c207370656369616c2e227da2646970667358221220668d48eb1f816d1ddc35de38ea2b4a14824c6087bb99575fea2489c30fe5a5c264736f6c63430008100033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000079d31bfca5fda7a4f15b36763d2e44c99d811a6c
-----Decoded View---------------
Arg [0] : owner (address): 0x79d31bFcA5Fda7A4F15b36763d2e44C99D811a6C
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000079d31bfca5fda7a4f15b36763d2e44c99d811a6c
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.