Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Overview
Max Total Supply
106 Ͼ721
Holders
23
Total Transfers
-
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Source Code Verified (Exact Match)
Contract Name:
CryptoPunks721
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.23; import {IStashFactory} from "../interfaces/IStashFactory.sol"; import {ICryptoPunks} from "../interfaces/ICryptoPunks.sol"; import {IStash} from "../interfaces/IStash.sol"; import {ILegacyWrappedPunks} from "../interfaces/ILegacyWrappedPunks.sol"; import {CryptoPunks721Metadata} from "./CryptoPunks721Metadata.sol"; import {Base64} from "solady/utils/Base64.sol"; import {ERC721} from "solady/tokens/ERC721.sol"; /** * @title CryptoPunks721 * @notice A modern wrapper to enable ERC721 functionality for CryptoPunks. */ contract CryptoPunks721 is ERC721, CryptoPunks721Metadata { error NotPunkOwner(); error PunkIsOwned(); IStashFactory private immutable _stashFactory; ICryptoPunks internal immutable _cryptoPunks; ILegacyWrappedPunks internal immutable _legacyWrapper; constructor(address stashFactory, address cryptoPunks, address legacyWrapper, address _punksMetadata) CryptoPunks721Metadata(_punksMetadata) { _stashFactory = IStashFactory(stashFactory); _cryptoPunks = ICryptoPunks(cryptoPunks); _legacyWrapper = ILegacyWrappedPunks(legacyWrapper); } function name() public pure override returns (string memory) { return "CryptoPunks 721"; } function symbol() public pure override returns (string memory) { return unicode"Ͼ721"; } function licensingTerms() public pure returns (string memory) { return "https://licenseterms.cryptopunks.app/"; } function tokenURI(uint256 tokenId) public view override returns (string memory) { // allow retrieving metadata for all valid wrapped punks, even if not (currently) wrapped. if (tokenId >= 10000) { revert TokenDoesNotExist(); } return string.concat("data:application/json;base64,", Base64.encode(bytes(stringURI(tokenId)))); } /** * @notice Wrap a CryptoPunk. Requires that the user has transferred their punk to their Stash. * @dev If the user does not have a Stash, one will be deployed for them. * @param punkIndex The index of the punk to wrap. */ function wrapPunk(uint256 punkIndex) external { address stash = _stashFactory.stashAddressFor(msg.sender); uint256 size; assembly { size := extcodesize(stash) } if (size == 0) { _stashFactory.deployStash(msg.sender); } IStash(stash).wrapPunk(punkIndex); _mint(msg.sender, punkIndex); } /** * @notice Wrap multiple CryptoPunks. Requires that the user has transferred their punks to their Stash. * @dev If the user does not have a Stash, one will be deployed for them. * @param punkIndexes An array of indexes of punks to wrap. */ function wrapPunkBatch(uint256[] calldata punkIndexes) external { address stash = _stashFactory.stashAddressFor(msg.sender); uint256 size; assembly { size := extcodesize(stash) } if (size == 0) { _stashFactory.deployStash(msg.sender); } for (uint256 i = 0; i < punkIndexes.length; ++i) { uint256 punkIndex = punkIndexes[i]; IStash(stash).wrapPunk(punkIndex); _mint(msg.sender, punkIndex); } } /** * @notice Unwrap a CryptoPunk. Requires that the caller owns or is approved to transfer the wrapped CryptoPunk. * @param punkIndex The index of the punk to unwrap */ function unwrapPunk(uint256 punkIndex) external { _burn(msg.sender, punkIndex); _cryptoPunks.transferPunk(msg.sender, punkIndex); } /** * @notice Unwrap multiple CryptoPunks. Requires that the caller owns or is approved to transfer the wrapped CryptoPunks. * @param punkIndexes An array of indexes of punks to unwrap */ function unwrapPunkBatch(uint256[] calldata punkIndexes) external { for (uint256 i = 0; i < punkIndexes.length; i++) { uint256 punkIndex = punkIndexes[i]; _burn(msg.sender, punkIndex); _cryptoPunks.transferPunk(msg.sender, punkIndex); } } /** * @notice Bulk migration tool to move legacy wrapped punks into the new wrapper. * @param punkIndexes The indexes of the punks to migrate. Must be owned by the caller. */ function migrateLegacyWrappedPunks(uint256[] calldata punkIndexes) external { for (uint256 i = 0; i < punkIndexes.length; ++i) { uint256 punkIndex = punkIndexes[i]; _legacyWrapper.transferFrom(msg.sender, address(this), punkIndex); _legacyWrapper.burn(punkIndex); _mint(msg.sender, punkIndex); } } /** * @dev Used for rescuing punks stuck in the contract, which would otherwise be trapped. * Punks that are properly wrapped can NOT be "rescued". This is open to the public so that * CryptoPunks Wrapped can remain open and ownerless. The alternatives are to either assign * an owner to the contract to manage withdrawing mistakenly deposited CryptoPunks, or to * allow the CryptoPunks to be trapped forever. Both of these alternatives were deemed * less desirable. */ function rescuePunk(uint256 punkIndex) external { if (_exists(punkIndex)) revert PunkIsOwned(); _cryptoPunks.transferPunk(msg.sender, punkIndex); } /** * @notice Returns the address of the Stash for a given user. * @param user The user to get the Stash for. */ function punkProxyForUser(address user) external view returns (address) { return _stashFactory.stashAddressFor(user); } /** * @notice Adapted from https://github.com/chiru-labs/ERC721A/blob/main/contracts/extensions/ERC721AQueryable.sol * @dev Returns an array of token IDs owned by `owner`. * * This function scans the ownership mapping and is O(`totalSupply`) in complexity. * It is meant to be called off-chain. */ function tokensOfOwner(address owner) external view returns (uint256[] memory) { unchecked { uint256 tokenIdsIdx; uint256 tokenIdsLength = balanceOf(owner); uint256[] memory tokenIds = new uint256[](tokenIdsLength); for (uint256 i = 0; tokenIdsIdx != tokenIdsLength; ++i) { address tokenOwner = _ownerOf(i); if (tokenOwner == owner) { tokenIds[tokenIdsIdx++] = i; } } return tokenIds; } } /** * @notice Returns the total number of CryptoPunks that have been wrapped. * @dev This total can be off if punks have been mistakenly deposited to the wrapper contract. * However, any mistakenly deposited punks are free to be withdrawn by anybody and thus should * theoretically not last in the contract for more than a block. */ function totalSupply() external view returns (uint256) { return _cryptoPunks.balanceOf(address(this)); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.23; interface IStashFactory { function isStash(address stash) external view returns (bool); function deployStash(address owner) external returns (address); function isAuction(address auction) external view returns (bool); function stashAddressFor(address owner) external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.23; interface ICryptoPunks { function punksOfferedForSale(uint256) external view returns (bool isForSale, uint256 punkIndex, address seller, uint256 minValue, address onlySellTo); function buyPunk(uint256) external payable; function transferPunk(address, uint256) external; function balanceOf(address) external view returns (uint256); function punkIndexToAddress(uint256) external view returns (address); function pendingWithdrawals(address) external view returns (uint256); function offerPunkForSaleToAddress(uint256, uint256, address) external; function getPunk(uint256 punkId) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.23; import {OrderType} from "../helpers/Enum.sol"; import {Order} from "../helpers/Struct.sol"; interface IStash { function placeOrder(uint80 pricePerUnit, uint16 numberOfUnits) external payable; function processOrder(uint80 pricePerUnit, uint16 numberOfUnits) external; function availableLiquidity(address tokenAddress) external view returns (uint256); function wrapPunk(uint256 punkIndex) external; function getOrder(address paymentToken) external view returns (Order memory); function withdraw(address tokenAddress, uint256 amount) external; function owner() external view returns (address); function version() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.23; interface ILegacyWrappedPunks { function transferFrom(address from, address to, uint256 tokenId) external; function proxyInfo(address) external view returns (address); function registerProxy() external; function burn(uint256 punkId) external; function mint(uint256 punkId) external; function approve(address to, uint256 punkId) external; function ownerOf(uint256 punkId) external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import {ICryptoPunksData} from "../interfaces/ICryptoPunksData.sol"; import {json} from "sol-json/json.sol"; import {Base64} from "solady/utils/Base64.sol"; import {LibString} from "solady/utils/LibString.sol"; /** * @title CryptoPunksWrappedMetadata * @author Modified from James Wenzel (emo.eth) (https://github.com/emo-eth/wrapped-punks/blob/main/src/PunksWrapperMetadata.sol) * @notice Abstract contract to fetch and format metadata for wrapped Punks. */ abstract contract CryptoPunks721Metadata { ICryptoPunksData public immutable PUNKS_DATA; constructor(address _punksData) { PUNKS_DATA = ICryptoPunksData(_punksData); } string private constant _BACKGROUND_FILL = '<rect width="100%" height="100%" fill="#66A670"/>'; /** * @dev Returns the string URI for a given token ID. * @param tokenId The index of the punk to get the URI for */ function stringURI(uint256 tokenId) internal view returns (string memory) { uint16 punkIndex = uint16(tokenId); string memory imageData = PUNKS_DATA.punkImageSvg(punkIndex); imageData = LibString.slice(imageData, 24); imageData = LibString.concat( LibString.slice(imageData, 0, 74), LibString.concat(_BACKGROUND_FILL, LibString.slice(imageData, 74)) ); string memory attributes = PUNKS_DATA.punkAttributes(punkIndex); attributes = parseAttributesArray(attributes); return json.object( string.concat( json.property("image", string.concat("data:image/svg+xml;base64,", Base64.encode(bytes(imageData)))), ",", json.rawProperty("attributes", attributes) ) ); } /** * @dev Parse a comma-separated list of attributes into a JSON array of attributes. Also calculates and appends an * "Attribute Count" attribute. * @param attributes The attributes string to parse */ function parseAttributesArray(string memory attributes) internal pure returns (string memory parsed) { string[] memory individualTraits = LibString.split(attributes, string(", ")); bytes1 firstChar = bytes(individualTraits[0])[0]; // only humans have skin tones, and their "type" always starts with M or F bool isHuman = firstChar == "M" || firstChar == "F"; string[] memory attributesArray; // placeholder if human string[] memory typeAndSkinToneIfHuman; if (isHuman) { // include an extra attribute for "Attribute Count" and an extra for "Skin Tone" attributesArray = new string[](individualTraits.length + 2); typeAndSkinToneIfHuman = LibString.split(individualTraits[0], " "); attributesArray[0] = createAttribute("Type", typeAndSkinToneIfHuman[0]); } else { attributesArray = new string[](individualTraits.length + 1); attributesArray[0] = createAttribute("Type", individualTraits[0]); } // "type" is not traditionally counted in the attribute count, nor is skin tone uint256 count = individualTraits.length - 1; // cryptopunks website refers to remaining attributes just as "Attributes" (versus OpenSea's "Accessories") string memory trait = "Attribute"; // start at 1 to skip "Type"; iterate over remaining attributes, if any for (uint256 i = 1; i < individualTraits.length; i++) { attributesArray[i] = createAttribute(trait, individualTraits[i]); } // add "Attribute Count" meta-attribute attributesArray[individualTraits.length] = createAttribute("Attribute Count", LibString.toString(count)); if (isHuman) { // add "Skin Tone" meta-attribute attributesArray[individualTraits.length + 1] = createAttribute("Skin Tone", typeAndSkinToneIfHuman[1]); } // concat all attributes into a single JSON array return json.arrayOf(attributesArray); } /** * @dev Create a single attribute JSON object. */ function createAttribute(string memory trait, string memory value) internal pure returns (string memory) { return json.object(string.concat(json.property("trait_type", trait), ",", json.property("value", value))); } }
// 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) { /// @solidity memory-safe-assembly 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 0x0670 will turn "-_" into "+/". mstore(0x1f, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef") mstore(0x3f, xor("ghijklmnopqrstuvwxyz0123456789-_", mul(iszero(fileSafe), 0x0670))) // 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. for {} 1 {} { data := add(data, 3) // Advance 3 bytes. let input := mload(data) // Write 4 bytes. Optimized for fewer stack operations. mstore8(0, mload(and(shr(18, input), 0x3F))) mstore8(1, mload(and(shr(12, input), 0x3F))) mstore8(2, mload(and(shr(6, input), 0x3F))) mstore8(3, mload(and(input, 0x3F))) mstore(ptr, mload(0x00)) ptr := add(ptr, 4) // Advance 4 bytes. if iszero(lt(ptr, end)) { break } } mstore(0x40, add(end, 0x20)) // Allocate the memory. // Equivalent to `o = [0, 2, 1][dataLength % 3]`. let o := div(2, mod(dataLength, 3)) // Offset `ptr` and pad with '='. We can simply write over the end. mstore(sub(ptr, o), shl(240, 0x3d3d)) // Set `o` to zero if there is padding. o := mul(iszero(iszero(noPadding)), o) mstore(sub(ptr, o), 0) // Zeroize the slot after the string. mstore(result, sub(encodedLength, o)) // Store the length. } } } /// @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 Decodes 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) { /// @solidity memory-safe-assembly assembly { let dataLength := mload(data) if dataLength { let decodedLength := mul(shr(2, dataLength), 3) for {} 1 {} { // If padded. if iszero(and(dataLength, 3)) { let t := xor(mload(add(data, dataLength)), 0x3d3d) // forgefmt: disable-next-item decodedLength := sub( decodedLength, add(iszero(byte(30, t)), iszero(byte(31, t))) ) break } // If non-padded. decodedLength := add(decodedLength, sub(and(dataLength, 3), 1)) break } result := mload(0x40) // Write the length of the bytes. mstore(result, decodedLength) // Skip the first slot, which stores the length. let ptr := add(result, 0x20) let end := add(ptr, decodedLength) // 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) for {} 1 {} { // Read 4 bytes. data := add(data, 4) let input := mload(data) // Write 3 bytes. // forgefmt: disable-next-item 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) if iszero(lt(ptr, end)) { break } } mstore(0x40, add(end, 0x20)) // Allocate the memory. mstore(end, 0) // Zeroize the slot after the bytes. mstore(0x60, 0) // Restore the zero slot. } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Simple ERC721 implementation with storage hitchhiking. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC721.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC721/ERC721.sol) /// /// @dev Note: /// - The ERC721 standard allows for self-approvals. /// For performance, this implementation WILL NOT revert for such actions. /// Please add any checks with overrides if desired. /// - For performance, methods are made payable where permitted by the ERC721 standard. /// - The `safeTransfer` functions use the identity precompile (0x4) /// to copy memory internally. /// /// If you are overriding: /// - NEVER violate the ERC721 invariant: /// the balance of an owner MUST always be equal to their number of ownership slots. /// The transfer functions do not have an underflow guard for user token balances. /// - Make sure all variables written to storage are properly cleaned // (e.g. the bool value for `isApprovedForAll` MUST be either 1 or 0 under the hood). /// - Check that the overridden function is actually used in the function you want to /// change the behavior of. Much of the code has been manually inlined for performance. abstract contract ERC721 { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev An account can hold up to 4294967295 tokens. uint256 internal constant _MAX_ACCOUNT_BALANCE = 0xffffffff; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Only the token owner or an approved account can manage the token. error NotOwnerNorApproved(); /// @dev The token does not exist. error TokenDoesNotExist(); /// @dev The token already exists. error TokenAlreadyExists(); /// @dev Cannot query the balance for the zero address. error BalanceQueryForZeroAddress(); /// @dev Cannot mint or transfer to the zero address. error TransferToZeroAddress(); /// @dev The token must be owned by `from`. error TransferFromIncorrectOwner(); /// @dev The recipient's balance has overflowed. error AccountBalanceOverflow(); /// @dev Cannot safely transfer to a contract that does not implement /// the ERC721Receiver interface. error TransferToNonERC721ReceiverImplementer(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EVENTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Emitted when token `id` is transferred from `from` to `to`. event Transfer(address indexed from, address indexed to, uint256 indexed id); /// @dev Emitted when `owner` enables `account` to manage the `id` token. event Approval(address indexed owner, address indexed account, uint256 indexed id); /// @dev Emitted when `owner` enables or disables `operator` to manage all of their tokens. event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved); /// @dev `keccak256(bytes("Transfer(address,address,uint256)"))`. uint256 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; /// @dev `keccak256(bytes("Approval(address,address,uint256)"))`. uint256 private constant _APPROVAL_EVENT_SIGNATURE = 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925; /// @dev `keccak256(bytes("ApprovalForAll(address,address,bool)"))`. uint256 private constant _APPROVAL_FOR_ALL_EVENT_SIGNATURE = 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STORAGE */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The ownership data slot of `id` is given by: /// ``` /// mstore(0x00, id) /// mstore(0x1c, _ERC721_MASTER_SLOT_SEED) /// let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) /// ``` /// Bits Layout: /// - [0..159] `addr` /// - [160..255] `extraData` /// /// The approved address slot is given by: `add(1, ownershipSlot)`. /// /// See: https://notes.ethereum.org/%40vbuterin/verkle_tree_eip /// /// The balance slot of `owner` is given by: /// ``` /// mstore(0x1c, _ERC721_MASTER_SLOT_SEED) /// mstore(0x00, owner) /// let balanceSlot := keccak256(0x0c, 0x1c) /// ``` /// Bits Layout: /// - [0..31] `balance` /// - [32..255] `aux` /// /// The `operator` approval slot of `owner` is given by: /// ``` /// mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator)) /// mstore(0x00, owner) /// let operatorApprovalSlot := keccak256(0x0c, 0x30) /// ``` uint256 private constant _ERC721_MASTER_SLOT_SEED = 0x7d8825530a5a2e7a << 192; /// @dev Pre-shifted and pre-masked constant. uint256 private constant _ERC721_MASTER_SLOT_SEED_MASKED = 0x0a5a2e7a00000000; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ERC721 METADATA */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the token collection name. function name() public view virtual returns (string memory); /// @dev Returns the token collection symbol. function symbol() public view virtual returns (string memory); /// @dev Returns the Uniform Resource Identifier (URI) for token `id`. function tokenURI(uint256 id) public view virtual returns (string memory); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ERC721 */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the owner of token `id`. /// /// Requirements: /// - Token `id` must exist. function ownerOf(uint256 id) public view virtual returns (address result) { result = _ownerOf(id); /// @solidity memory-safe-assembly assembly { if iszero(result) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } } } /// @dev Returns the number of tokens owned by `owner`. /// /// Requirements: /// - `owner` must not be the zero address. function balanceOf(address owner) public view virtual returns (uint256 result) { /// @solidity memory-safe-assembly assembly { // Revert if the `owner` is the zero address. if iszero(owner) { mstore(0x00, 0x8f4eb604) // `BalanceQueryForZeroAddress()`. revert(0x1c, 0x04) } mstore(0x1c, _ERC721_MASTER_SLOT_SEED) mstore(0x00, owner) result := and(sload(keccak256(0x0c, 0x1c)), _MAX_ACCOUNT_BALANCE) } } /// @dev Returns the account approved to manage token `id`. /// /// Requirements: /// - Token `id` must exist. function getApproved(uint256 id) public view virtual returns (address result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) if iszero(shl(96, sload(ownershipSlot))) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } result := sload(add(1, ownershipSlot)) } } /// @dev Sets `account` as the approved account to manage token `id`. /// /// Requirements: /// - Token `id` must exist. /// - The caller must be the owner of the token, /// or an approved operator for the token owner. /// /// Emits an {Approval} event. function approve(address account, uint256 id) public payable virtual { _approve(msg.sender, account, id); } /// @dev Returns whether `operator` is approved to manage the tokens of `owner`. function isApprovedForAll(address owner, address operator) public view virtual returns (bool result) { /// @solidity memory-safe-assembly assembly { mstore(0x1c, operator) mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED) mstore(0x00, owner) result := sload(keccak256(0x0c, 0x30)) } } /// @dev Sets whether `operator` is approved to manage the tokens of the caller. /// /// Emits an {ApprovalForAll} event. function setApprovalForAll(address operator, bool isApproved) public virtual { /// @solidity memory-safe-assembly assembly { // Convert to 0 or 1. isApproved := iszero(iszero(isApproved)) // Update the `isApproved` for (`msg.sender`, `operator`). mstore(0x1c, operator) mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED) mstore(0x00, caller()) sstore(keccak256(0x0c, 0x30), isApproved) // Emit the {ApprovalForAll} event. mstore(0x00, isApproved) // forgefmt: disable-next-item log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), shr(96, shl(96, operator))) } } /// @dev Transfers token `id` from `from` to `to`. /// /// Requirements: /// /// - Token `id` must exist. /// - `from` must be the owner of the token. /// - `to` cannot be the zero address. /// - The caller must be the owner of the token, or be approved to manage the token. /// /// Emits a {Transfer} event. function transferFrom(address from, address to, uint256 id) public payable virtual { _beforeTokenTransfer(from, to, id); /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. let bitmaskAddress := shr(96, not(0)) from := and(bitmaskAddress, from) to := and(bitmaskAddress, to) // Load the ownership data. mstore(0x00, id) mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, caller())) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let ownershipPacked := sload(ownershipSlot) let owner := and(bitmaskAddress, ownershipPacked) // Revert if `from` is not the owner, or does not exist. if iszero(mul(owner, eq(owner, from))) { if iszero(owner) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } mstore(0x00, 0xa1148100) // `TransferFromIncorrectOwner()`. revert(0x1c, 0x04) } // Revert if `to` is the zero address. if iszero(to) { mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. revert(0x1c, 0x04) } // Load, check, and update the token approval. { mstore(0x00, from) let approvedAddress := sload(add(1, ownershipSlot)) // Revert if the caller is not the owner, nor approved. if iszero(or(eq(caller(), from), eq(caller(), approvedAddress))) { if iszero(sload(keccak256(0x0c, 0x30))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Delete the approved address if any. if approvedAddress { sstore(add(1, ownershipSlot), 0) } } // Update with the new owner. sstore(ownershipSlot, xor(ownershipPacked, xor(from, to))) // Decrement the balance of `from`. { let fromBalanceSlot := keccak256(0x0c, 0x1c) sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1)) } // Increment the balance of `to`. { mstore(0x00, to) let toBalanceSlot := keccak256(0x0c, 0x1c) let toBalanceSlotPacked := add(sload(toBalanceSlot), 1) if iszero(and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE)) { mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. revert(0x1c, 0x04) } sstore(toBalanceSlot, toBalanceSlotPacked) } // Emit the {Transfer} event. log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id) } _afterTokenTransfer(from, to, id); } /// @dev Equivalent to `safeTransferFrom(from, to, id, "")`. function safeTransferFrom(address from, address to, uint256 id) public payable virtual { transferFrom(from, to, id); if (_hasCode(to)) _checkOnERC721Received(from, to, id, ""); } /// @dev Transfers token `id` from `from` to `to`. /// /// Requirements: /// /// - Token `id` must exist. /// - `from` must be the owner of the token. /// - `to` cannot be the zero address. /// - The caller must be the owner of the token, or be approved to manage the token. /// - 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 id, bytes calldata data) public payable virtual { transferFrom(from, to, id); if (_hasCode(to)) _checkOnERC721Received(from, to, id, data); } /// @dev Returns true if this contract implements the interface defined by `interfaceId`. /// See: https://eips.ethereum.org/EIPS/eip-165 /// This function call must use less than 30000 gas. function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) { /// @solidity memory-safe-assembly assembly { let s := shr(224, interfaceId) // ERC165: 0x01ffc9a7, ERC721: 0x80ac58cd, ERC721Metadata: 0x5b5e139f. result := or(or(eq(s, 0x01ffc9a7), eq(s, 0x80ac58cd)), eq(s, 0x5b5e139f)) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL QUERY FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns if token `id` exists. function _exists(uint256 id) internal view virtual returns (bool result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) result := iszero(iszero(shl(96, sload(add(id, add(id, keccak256(0x00, 0x20))))))) } } /// @dev Returns the owner of token `id`. /// Returns the zero address instead of reverting if the token does not exist. function _ownerOf(uint256 id) internal view virtual returns (address result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) result := shr(96, shl(96, sload(add(id, add(id, keccak256(0x00, 0x20)))))) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL DATA HITCHHIKING FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // For performance, no events are emitted for the hitchhiking setters. // Please emit your own events if required. /// @dev Returns the auxiliary data for `owner`. /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data. /// Auxiliary data can be set for any address, even if it does not have any tokens. function _getAux(address owner) internal view virtual returns (uint224 result) { /// @solidity memory-safe-assembly assembly { mstore(0x1c, _ERC721_MASTER_SLOT_SEED) mstore(0x00, owner) result := shr(32, sload(keccak256(0x0c, 0x1c))) } } /// @dev Set the auxiliary data for `owner` to `value`. /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data. /// Auxiliary data can be set for any address, even if it does not have any tokens. function _setAux(address owner, uint224 value) internal virtual { /// @solidity memory-safe-assembly assembly { mstore(0x1c, _ERC721_MASTER_SLOT_SEED) mstore(0x00, owner) let balanceSlot := keccak256(0x0c, 0x1c) let packed := sload(balanceSlot) sstore(balanceSlot, xor(packed, shl(32, xor(value, shr(32, packed))))) } } /// @dev Returns the extra data for token `id`. /// Minting, transferring, burning a token will not change the extra data. /// The extra data can be set on a non-existent token. function _getExtraData(uint256 id) internal view virtual returns (uint96 result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) result := shr(160, sload(add(id, add(id, keccak256(0x00, 0x20))))) } } /// @dev Sets the extra data for token `id` to `value`. /// Minting, transferring, burning a token will not change the extra data. /// The extra data can be set on a non-existent token. function _setExtraData(uint256 id, uint96 value) internal virtual { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let packed := sload(ownershipSlot) sstore(ownershipSlot, xor(packed, shl(160, xor(value, shr(160, packed))))) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL MINT FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Mints token `id` to `to`. /// /// Requirements: /// /// - Token `id` must not exist. /// - `to` cannot be the zero address. /// /// Emits a {Transfer} event. function _mint(address to, uint256 id) internal virtual { _beforeTokenTransfer(address(0), to, id); /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. to := shr(96, shl(96, to)) // Revert if `to` is the zero address. if iszero(to) { mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. revert(0x1c, 0x04) } // Load the ownership data. mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let ownershipPacked := sload(ownershipSlot) // Revert if the token already exists. if shl(96, ownershipPacked) { mstore(0x00, 0xc991cbb1) // `TokenAlreadyExists()`. revert(0x1c, 0x04) } // Update with the owner. sstore(ownershipSlot, or(ownershipPacked, to)) // Increment the balance of the owner. { mstore(0x00, to) let balanceSlot := keccak256(0x0c, 0x1c) let balanceSlotPacked := add(sload(balanceSlot), 1) if iszero(and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE)) { mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. revert(0x1c, 0x04) } sstore(balanceSlot, balanceSlotPacked) } // Emit the {Transfer} event. log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id) } _afterTokenTransfer(address(0), to, id); } /// @dev Equivalent to `_safeMint(to, id, "")`. function _safeMint(address to, uint256 id) internal virtual { _safeMint(to, id, ""); } /// @dev Mints token `id` to `to`. /// /// Requirements: /// /// - Token `id` must not exist. /// - `to` cannot be the zero address. /// - 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 id, bytes memory data) internal virtual { _mint(to, id); if (_hasCode(to)) _checkOnERC721Received(address(0), to, id, data); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL BURN FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Equivalent to `_burn(address(0), id)`. function _burn(uint256 id) internal virtual { _burn(address(0), id); } /// @dev Destroys token `id`, using `by`. /// /// Requirements: /// /// - Token `id` must exist. /// - If `by` is not the zero address, /// it must be the owner of the token, or be approved to manage the token. /// /// Emits a {Transfer} event. function _burn(address by, uint256 id) internal virtual { address owner = ownerOf(id); _beforeTokenTransfer(owner, address(0), id); /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. by := shr(96, shl(96, by)) // Load the ownership data. mstore(0x00, id) mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by)) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let ownershipPacked := sload(ownershipSlot) // Reload the owner in case it is changed in `_beforeTokenTransfer`. owner := shr(96, shl(96, ownershipPacked)) // Revert if the token does not exist. if iszero(owner) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } // Load and check the token approval. { mstore(0x00, owner) let approvedAddress := sload(add(1, ownershipSlot)) // If `by` is not the zero address, do the authorization check. // Revert if the `by` is not the owner, nor approved. if iszero(or(iszero(by), or(eq(by, owner), eq(by, approvedAddress)))) { if iszero(sload(keccak256(0x0c, 0x30))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Delete the approved address if any. if approvedAddress { sstore(add(1, ownershipSlot), 0) } } // Clear the owner. sstore(ownershipSlot, xor(ownershipPacked, owner)) // Decrement the balance of `owner`. { let balanceSlot := keccak256(0x0c, 0x1c) sstore(balanceSlot, sub(sload(balanceSlot), 1)) } // Emit the {Transfer} event. log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, owner, 0, id) } _afterTokenTransfer(owner, address(0), id); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL APPROVAL FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns whether `account` is the owner of token `id`, or is approved to manage it. /// /// Requirements: /// - Token `id` must exist. function _isApprovedOrOwner(address account, uint256 id) internal view virtual returns (bool result) { /// @solidity memory-safe-assembly assembly { result := 1 // Clear the upper 96 bits. account := shr(96, shl(96, account)) // Load the ownership data. mstore(0x00, id) mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, account)) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let owner := shr(96, shl(96, sload(ownershipSlot))) // Revert if the token does not exist. if iszero(owner) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } // Check if `account` is the `owner`. if iszero(eq(account, owner)) { mstore(0x00, owner) // Check if `account` is approved to manage the token. if iszero(sload(keccak256(0x0c, 0x30))) { result := eq(account, sload(add(1, ownershipSlot))) } } } } /// @dev Returns the account approved to manage token `id`. /// Returns the zero address instead of reverting if the token does not exist. function _getApproved(uint256 id) internal view virtual returns (address result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) result := sload(add(1, add(id, add(id, keccak256(0x00, 0x20))))) } } /// @dev Equivalent to `_approve(address(0), account, id)`. function _approve(address account, uint256 id) internal virtual { _approve(address(0), account, id); } /// @dev Sets `account` as the approved account to manage token `id`, using `by`. /// /// Requirements: /// - Token `id` must exist. /// - If `by` is not the zero address, `by` must be the owner /// or an approved operator for the token owner. /// /// Emits a {Transfer} event. function _approve(address by, address account, uint256 id) internal virtual { assembly { // Clear the upper 96 bits. let bitmaskAddress := shr(96, not(0)) account := and(bitmaskAddress, account) by := and(bitmaskAddress, by) // Load the owner of the token. mstore(0x00, id) mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by)) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let owner := and(bitmaskAddress, sload(ownershipSlot)) // Revert if the token does not exist. if iszero(owner) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } // If `by` is not the zero address, do the authorization check. // Revert if `by` is not the owner, nor approved. if iszero(or(iszero(by), eq(by, owner))) { mstore(0x00, owner) if iszero(sload(keccak256(0x0c, 0x30))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Sets `account` as the approved account to manage `id`. sstore(add(1, ownershipSlot), account) // Emit the {Approval} event. log4(codesize(), 0x00, _APPROVAL_EVENT_SIGNATURE, owner, account, id) } } /// @dev Approve or remove the `operator` as an operator for `by`, /// without authorization checks. /// /// Emits an {ApprovalForAll} event. function _setApprovalForAll(address by, address operator, bool isApproved) internal virtual { /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. by := shr(96, shl(96, by)) operator := shr(96, shl(96, operator)) // Convert to 0 or 1. isApproved := iszero(iszero(isApproved)) // Update the `isApproved` for (`by`, `operator`). mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator)) mstore(0x00, by) sstore(keccak256(0x0c, 0x30), isApproved) // Emit the {ApprovalForAll} event. mstore(0x00, isApproved) log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, by, operator) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL TRANSFER FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Equivalent to `_transfer(address(0), from, to, id)`. function _transfer(address from, address to, uint256 id) internal virtual { _transfer(address(0), from, to, id); } /// @dev Transfers token `id` from `from` to `to`. /// /// Requirements: /// /// - Token `id` must exist. /// - `from` must be the owner of the token. /// - `to` cannot be the zero address. /// - If `by` is not the zero address, /// it must be the owner of the token, or be approved to manage the token. /// /// Emits a {Transfer} event. function _transfer(address by, address from, address to, uint256 id) internal virtual { _beforeTokenTransfer(from, to, id); /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. let bitmaskAddress := shr(96, not(0)) from := and(bitmaskAddress, from) to := and(bitmaskAddress, to) by := and(bitmaskAddress, by) // Load the ownership data. mstore(0x00, id) mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by)) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let ownershipPacked := sload(ownershipSlot) let owner := and(bitmaskAddress, ownershipPacked) // Revert if `from` is not the owner, or does not exist. if iszero(mul(owner, eq(owner, from))) { if iszero(owner) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } mstore(0x00, 0xa1148100) // `TransferFromIncorrectOwner()`. revert(0x1c, 0x04) } // Revert if `to` is the zero address. if iszero(to) { mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. revert(0x1c, 0x04) } // Load, check, and update the token approval. { mstore(0x00, from) let approvedAddress := sload(add(1, ownershipSlot)) // If `by` is not the zero address, do the authorization check. // Revert if the `by` is not the owner, nor approved. if iszero(or(iszero(by), or(eq(by, from), eq(by, approvedAddress)))) { if iszero(sload(keccak256(0x0c, 0x30))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Delete the approved address if any. if approvedAddress { sstore(add(1, ownershipSlot), 0) } } // Update with the new owner. sstore(ownershipSlot, xor(ownershipPacked, xor(from, to))) // Decrement the balance of `from`. { let fromBalanceSlot := keccak256(0x0c, 0x1c) sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1)) } // Increment the balance of `to`. { mstore(0x00, to) let toBalanceSlot := keccak256(0x0c, 0x1c) let toBalanceSlotPacked := add(sload(toBalanceSlot), 1) if iszero(and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE)) { mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. revert(0x1c, 0x04) } sstore(toBalanceSlot, toBalanceSlotPacked) } // Emit the {Transfer} event. log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id) } _afterTokenTransfer(from, to, id); } /// @dev Equivalent to `_safeTransfer(from, to, id, "")`. function _safeTransfer(address from, address to, uint256 id) internal virtual { _safeTransfer(from, to, id, ""); } /// @dev Transfers token `id` from `from` to `to`. /// /// Requirements: /// /// - Token `id` must exist. /// - `from` must be the owner of the token. /// - `to` cannot be the zero address. /// - The caller must be the owner of the token, or be approved to manage the token. /// - 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 id, bytes memory data) internal virtual { _transfer(address(0), from, to, id); if (_hasCode(to)) _checkOnERC721Received(from, to, id, data); } /// @dev Equivalent to `_safeTransfer(by, from, to, id, "")`. function _safeTransfer(address by, address from, address to, uint256 id) internal virtual { _safeTransfer(by, from, to, id, ""); } /// @dev Transfers token `id` from `from` to `to`. /// /// Requirements: /// /// - Token `id` must exist. /// - `from` must be the owner of the token. /// - `to` cannot be the zero address. /// - If `by` is not the zero address, /// it must be the owner of the token, or be approved to manage the token. /// - 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 by, address from, address to, uint256 id, bytes memory data) internal virtual { _transfer(by, from, to, id); if (_hasCode(to)) _checkOnERC721Received(from, to, id, data); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* HOOKS FOR OVERRIDING */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Hook that is called before any token transfers, including minting and burning. function _beforeTokenTransfer(address from, address to, uint256 id) internal virtual {} /// @dev Hook that is called after any token transfers, including minting and burning. function _afterTokenTransfer(address from, address to, uint256 id) internal virtual {} /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PRIVATE HELPERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns if `a` has bytecode of non-zero length. function _hasCode(address a) private view returns (bool result) { /// @solidity memory-safe-assembly assembly { result := extcodesize(a) // Can handle dirty upper bits. } } /// @dev Perform a call to invoke {IERC721Receiver-onERC721Received} on `to`. /// Reverts if the target does not support the function correctly. function _checkOnERC721Received(address from, address to, uint256 id, bytes memory data) private { /// @solidity memory-safe-assembly assembly { // Prepare the calldata. let m := mload(0x40) let onERC721ReceivedSelector := 0x150b7a02 mstore(m, onERC721ReceivedSelector) mstore(add(m, 0x20), caller()) // The `operator`, which is always `msg.sender`. mstore(add(m, 0x40), shr(96, shl(96, from))) mstore(add(m, 0x60), id) mstore(add(m, 0x80), 0x80) let n := mload(data) mstore(add(m, 0xa0), n) if n { pop(staticcall(gas(), 4, add(data, 0x20), n, add(m, 0xc0), n)) } // Revert if the call reverts. if iszero(call(gas(), to, 0, add(m, 0x1c), add(n, 0xa4), m, 0x20)) { if returndatasize() { // Bubble up the revert if the call reverts. returndatacopy(m, 0x00, returndatasize()) revert(m, returndatasize()) } } // Load the returndata and compare it. if iszero(eq(mload(m), shl(224, onERC721ReceivedSelector))) { mstore(0x00, 0xd1a57ed6) // `TransferToNonERC721ReceiverImplementer()`. revert(0x1c, 0x04) } } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.23; enum OrderType { // 0: Can replace previous bid. Alters bid price and adds `numberOfUnits` SUBSEQUENT_BIDS_OVERWRITE_PRICE_AND_ADD_UNITS, // 1: Can replace previous bid if new bid has higher `pricePerUnit` SUBSEQUENT_BIDS_REPLACE_EXISTING_PRICE_INCREASE_REQUIRED, // 2: Cannot replace previous bid under any circumstance UNREPLACEABLE }
// SPDX-License-Identifier: MIT pragma solidity 0.8.23; import {OrderType} from "./Enum.sol"; struct Order { uint16 numberOfUnits; uint80 pricePerUnit; address auction; } struct PunkBid { Order order; uint256 accountNonce; uint256 bidNonce; uint256 expiration; bytes32 root; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; interface ICryptoPunksData { function addAsset(uint8 index, bytes memory encoding, string memory name) external; function addComposites( uint64 key1, uint32 value1, uint64 key2, uint32 value2, uint64 key3, uint32 value3, uint64 key4, uint32 value4 ) external; function addPunks(uint8 index, bytes memory _punks) external; function punkAttributes(uint16 index) external view returns (string memory text); function punkImage(uint16 index) external view returns (bytes memory); function punkImageSvg(uint16 index) external view returns (string memory svg); function sealContract() external; function setPalette(bytes memory _palette) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import { LibString } from "solady/utils/LibString.sol"; library json { using LibString for string; /** * @notice enclose a string in {braces} * Note: does not escape quotes in value * @param value string to enclose in braces * @return string of {value} */ function object(string memory value) internal pure returns (string memory) { return string.concat("{", value, "}"); } /** * @notice enclose a string in [brackets] * Note: does not escape quotes in value * @param value string to enclose in brackets * @return string of [value] */ function array(string memory value) internal pure returns (string memory) { return string.concat("[", value, "]"); } /** * @notice enclose name and value with quotes, and place a colon "between":"them". * Note: escapes quotes in name and value * @param name name of property * @param value value of property * @return string of "name":"value" */ function property(string memory name, string memory value) internal pure returns (string memory) { return string.concat('"', name.escapeJSON(), '":"', value.escapeJSON(), '"'); } /** * @notice enclose name with quotes, but not rawValue, and place a colon "between":them * Note: escapes quotes in name, but not value (which may itself be a JSON object, array, etc) * @param name name of property * @param rawValue raw value of property, which will not be enclosed in quotes * @return string of "name":value */ function rawProperty(string memory name, string memory rawValue) internal pure returns (string memory) { return string.concat('"', name.escapeJSON(), '":', rawValue); } /** * @notice comma-join an array of properties and {"enclose":"them","in":"braces"} * Note: does not escape quotes in properties, as it assumes they are already escaped * @param properties array of '"name":"value"' properties to join * @return string of {"name":"value","name":"value",...} */ function objectOf(string[] memory properties) internal pure returns (string memory) { if (properties.length == 0) { return object(""); } string memory result = properties[0]; for (uint256 i = 1; i < properties.length; ++i) { result = string.concat(result, ",", properties[i]); } return object(result); } /** * @notice comma-join an array of values and enclose them [in,brackets] * Note: does not escape quotes in values, as it assumes they are already escaped * @param values array of values to join * @return string of [value,value,...] */ function arrayOf(string[] memory values) internal pure returns (string memory) { return array(_commaJoin(values)); } /** * @notice comma-join two arrays of values and [enclose,them,in,brackets] * Note: does not escape quotes in values, as it assumes they are already escaped * @param values1 first array of values to join * @param values2 second array of values to join * @return string of [values1_0,values1_1,values2_0,values2_1...] */ function arrayOf(string[] memory values1, string[] memory values2) internal pure returns (string memory) { if (values1.length == 0) { return arrayOf(values2); } else if (values2.length == 0) { return arrayOf(values1); } return array(string.concat(_commaJoin(values1), ",", _commaJoin(values2))); } /** * @notice enclose a string in double "quotes", escaping any existing quotes * @param str string to enclose in quotes * @return string of "value" */ function quote(string memory str) internal pure returns (string memory) { return string.concat('"', str.escapeJSON(), '"'); } /** * @notice comma-join an array of strings * @param values array of strings to join * @return string of value,value,... */ function _commaJoin(string[] memory values) internal pure returns (string memory) { return _join(values, ","); } /** * @notice join two strings with a comma * @param value1 first string * @param value2 second string * @return string of value1,value2 */ function _commaJoin(string memory value1, string memory value2) internal pure returns (string memory) { return string.concat(value1, ",", value2); } /** * @notice join an array of strings with a specified separator * @param values array of strings to join * @param separator separator to join with * @return string of value<separator>value<separator>... */ function _join(string[] memory values, string memory separator) internal pure returns (string memory) { if (values.length == 0) { return ""; } string memory result = values[0]; for (uint256 i = 1; i < values.length; ++i) { result = string.concat(result, separator, values[i]); } return result; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Library for converting numbers into strings and other string operations. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibString.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol) library LibString { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The length of the output is too small to contain all the hex digits. error HexLengthInsufficient(); /// @dev The length of the string is more than 32 bytes. error TooBigForSmallString(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The constant returned when the `search` is not found in the string. uint256 internal constant NOT_FOUND = type(uint256).max; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* DECIMAL OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the base 10 decimal representation of `value`. function toString(uint256 value) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. str := add(mload(0x40), 0x80) // Update the free memory pointer to allocate. mstore(0x40, add(str, 0x20)) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str let w := not(0) // Tsk. // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. for { let temp := value } 1 {} { str := add(str, w) // `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) if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } /// @dev Returns the base 10 decimal representation of `value`. function toString(int256 value) internal pure returns (string memory str) { if (value >= 0) { return toString(uint256(value)); } unchecked { str = toString(uint256(-value)); } /// @solidity memory-safe-assembly assembly { // We still have some spare memory space on the left, // as we have allocated 3 words (96 bytes) for up to 78 digits. let length := mload(str) // Load the string length. mstore(str, 0x2d) // Store the '-' character. str := sub(str, 1) // Move back the string pointer by a byte. mstore(str, add(length, 1)) // Update the string length. } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* HEXADECIMAL OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the hexadecimal representation of `value`, /// left-padded to an input length of `length` bytes. /// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte, /// giving a total length of `length * 2 + 2` bytes. /// Reverts if `length` is too small for the output to contain all the digits. function toHexString(uint256 value, uint256 length) internal pure returns (string memory str) { str = toHexStringNoPrefix(value, length); /// @solidity memory-safe-assembly assembly { let strLength := add(mload(str), 2) // Compute the length. mstore(str, 0x3078) // Write the "0x" prefix. str := sub(str, 2) // Move the pointer. mstore(str, strLength) // Write the length. } } /// @dev Returns the hexadecimal representation of `value`, /// left-padded to an input length of `length` bytes. /// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte, /// giving a total length of `length * 2` bytes. /// Reverts if `length` is too small for the output to contain all the digits. function toHexStringNoPrefix(uint256 value, uint256 length) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { // We need 0x20 bytes for the trailing zeros padding, `length * 2` bytes // for the digits, 0x02 bytes for the prefix, and 0x20 bytes for the length. // We add 0x20 to the total and round down to a multiple of 0x20. // (0x20 + 0x20 + 0x02 + 0x20) = 0x62. str := add(mload(0x40), and(add(shl(1, length), 0x42), not(0x1f))) // Allocate the memory. mstore(0x40, add(str, 0x20)) // Zeroize the slot after the string. mstore(str, 0) // Cache the end to calculate the length later. let end := str // Store "0123456789abcdef" in scratch space. mstore(0x0f, 0x30313233343536373839616263646566) let start := sub(str, add(length, length)) let w := not(1) // Tsk. let temp := value // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. for {} 1 {} { str := add(str, w) // `sub(str, 2)`. mstore8(add(str, 1), mload(and(temp, 15))) mstore8(str, mload(and(shr(4, temp), 15))) temp := shr(8, temp) if iszero(xor(str, start)) { break } } if temp { mstore(0x00, 0x2194895a) // `HexLengthInsufficient()`. revert(0x1c, 0x04) } // Compute the string's length. let strLength := sub(end, str) // Move the pointer and write the length. str := sub(str, 0x20) mstore(str, strLength) } } /// @dev Returns the hexadecimal representation of `value`. /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte. /// As address are 20 bytes long, the output will left-padded to have /// a length of `20 * 2 + 2` bytes. function toHexString(uint256 value) internal pure returns (string memory str) { str = toHexStringNoPrefix(value); /// @solidity memory-safe-assembly assembly { let strLength := add(mload(str), 2) // Compute the length. mstore(str, 0x3078) // Write the "0x" prefix. str := sub(str, 2) // Move the pointer. mstore(str, strLength) // Write the length. } } /// @dev Returns the hexadecimal representation of `value`. /// The output is prefixed with "0x". /// The output excludes leading "0" from the `toHexString` output. /// `0x00: "0x0", 0x01: "0x1", 0x12: "0x12", 0x123: "0x123"`. function toMinimalHexString(uint256 value) internal pure returns (string memory str) { str = toHexStringNoPrefix(value); /// @solidity memory-safe-assembly assembly { let o := eq(byte(0, mload(add(str, 0x20))), 0x30) // Whether leading zero is present. let strLength := add(mload(str), 2) // Compute the length. mstore(add(str, o), 0x3078) // Write the "0x" prefix, accounting for leading zero. str := sub(add(str, o), 2) // Move the pointer, accounting for leading zero. mstore(str, sub(strLength, o)) // Write the length, accounting for leading zero. } } /// @dev Returns the hexadecimal representation of `value`. /// The output excludes leading "0" from the `toHexStringNoPrefix` output. /// `0x00: "0", 0x01: "1", 0x12: "12", 0x123: "123"`. function toMinimalHexStringNoPrefix(uint256 value) internal pure returns (string memory str) { str = toHexStringNoPrefix(value); /// @solidity memory-safe-assembly assembly { let o := eq(byte(0, mload(add(str, 0x20))), 0x30) // Whether leading zero is present. let strLength := mload(str) // Get the length. str := add(str, o) // Move the pointer, accounting for leading zero. mstore(str, sub(strLength, o)) // Write the length, accounting for leading zero. } } /// @dev Returns the hexadecimal representation of `value`. /// The output is encoded using 2 hexadecimal digits per byte. /// As address are 20 bytes long, the output will left-padded to have /// a length of `20 * 2` bytes. function toHexStringNoPrefix(uint256 value) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length, // 0x02 bytes for the prefix, and 0x40 bytes for the digits. // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x40) is 0xa0. str := add(mload(0x40), 0x80) // Allocate the memory. mstore(0x40, add(str, 0x20)) // Zeroize the slot after the string. mstore(str, 0) // Cache the end to calculate the length later. let end := str // Store "0123456789abcdef" in scratch space. mstore(0x0f, 0x30313233343536373839616263646566) let w := not(1) // Tsk. // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. for { let temp := value } 1 {} { str := add(str, w) // `sub(str, 2)`. mstore8(add(str, 1), mload(and(temp, 15))) mstore8(str, mload(and(shr(4, temp), 15))) temp := shr(8, temp) if iszero(temp) { break } } // Compute the string's length. let strLength := sub(end, str) // Move the pointer and write the length. str := sub(str, 0x20) mstore(str, strLength) } } /// @dev Returns the hexadecimal representation of `value`. /// The output is prefixed with "0x", encoded using 2 hexadecimal digits per byte, /// and the alphabets are capitalized conditionally according to /// https://eips.ethereum.org/EIPS/eip-55 function toHexStringChecksummed(address value) internal pure returns (string memory str) { str = toHexString(value); /// @solidity memory-safe-assembly assembly { let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...` let o := add(str, 0x22) let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... ` let t := shl(240, 136) // `0b10001000 << 240` for { let i := 0 } 1 {} { mstore(add(i, i), mul(t, byte(i, hashed))) i := add(i, 1) if eq(i, 20) { break } } mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask))))) o := add(o, 0x20) mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask))))) } } /// @dev Returns the hexadecimal representation of `value`. /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte. function toHexString(address value) internal pure returns (string memory str) { str = toHexStringNoPrefix(value); /// @solidity memory-safe-assembly assembly { let strLength := add(mload(str), 2) // Compute the length. mstore(str, 0x3078) // Write the "0x" prefix. str := sub(str, 2) // Move the pointer. mstore(str, strLength) // Write the length. } } /// @dev Returns the hexadecimal representation of `value`. /// The output is encoded using 2 hexadecimal digits per byte. function toHexStringNoPrefix(address value) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { str := mload(0x40) // Allocate the memory. // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length, // 0x02 bytes for the prefix, and 0x28 bytes for the digits. // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80. mstore(0x40, add(str, 0x80)) // Store "0123456789abcdef" in scratch space. mstore(0x0f, 0x30313233343536373839616263646566) str := add(str, 2) mstore(str, 40) let o := add(str, 0x20) mstore(add(o, 40), 0) value := shl(96, value) // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. for { let i := 0 } 1 {} { let p := add(o, add(i, i)) let temp := byte(i, value) mstore8(add(p, 1), mload(and(temp, 15))) mstore8(p, mload(shr(4, temp))) i := add(i, 1) if eq(i, 20) { break } } } } /// @dev Returns the hex encoded string from the raw bytes. /// The output is encoded using 2 hexadecimal digits per byte. function toHexString(bytes memory raw) internal pure returns (string memory str) { str = toHexStringNoPrefix(raw); /// @solidity memory-safe-assembly assembly { let strLength := add(mload(str), 2) // Compute the length. mstore(str, 0x3078) // Write the "0x" prefix. str := sub(str, 2) // Move the pointer. mstore(str, strLength) // Write the length. } } /// @dev Returns the hex encoded string from the raw bytes. /// The output is encoded using 2 hexadecimal digits per byte. function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { let length := mload(raw) str := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix. mstore(str, add(length, length)) // Store the length of the output. // Store "0123456789abcdef" in scratch space. mstore(0x0f, 0x30313233343536373839616263646566) let o := add(str, 0x20) let end := add(raw, length) for {} iszero(eq(raw, end)) {} { raw := add(raw, 1) mstore8(add(o, 1), mload(and(mload(raw), 15))) mstore8(o, mload(and(shr(4, mload(raw)), 15))) o := add(o, 2) } mstore(o, 0) // Zeroize the slot after the string. mstore(0x40, add(o, 0x20)) // Allocate the memory. } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* RUNE STRING OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the number of UTF characters in the string. function runeCount(string memory s) internal pure returns (uint256 result) { /// @solidity memory-safe-assembly assembly { if mload(s) { mstore(0x00, div(not(0), 255)) mstore(0x20, 0x0202020202020202020202020202020202020202020202020303030304040506) let o := add(s, 0x20) let end := add(o, mload(s)) for { result := 1 } 1 { result := add(result, 1) } { o := add(o, byte(0, mload(shr(250, mload(o))))) if iszero(lt(o, end)) { break } } } } } /// @dev Returns if this string is a 7-bit ASCII string. /// (i.e. all characters codes are in [0..127]) function is7BitASCII(string memory s) internal pure returns (bool result) { /// @solidity memory-safe-assembly assembly { let mask := shl(7, div(not(0), 255)) result := 1 let n := mload(s) if n { let o := add(s, 0x20) let end := add(o, n) let last := mload(end) mstore(end, 0) for {} 1 {} { if and(mask, mload(o)) { result := 0 break } o := add(o, 0x20) if iszero(lt(o, end)) { break } } mstore(end, last) } } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* BYTE STRING OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // For performance and bytecode compactness, all indices of the following operations // are byte (ASCII) offsets, not UTF character offsets. /// @dev Returns `subject` all occurrences of `search` replaced with `replacement`. function replace(string memory subject, string memory search, string memory replacement) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let subjectLength := mload(subject) let searchLength := mload(search) let replacementLength := mload(replacement) subject := add(subject, 0x20) search := add(search, 0x20) replacement := add(replacement, 0x20) result := add(mload(0x40), 0x20) let subjectEnd := add(subject, subjectLength) if iszero(gt(searchLength, subjectLength)) { let subjectSearchEnd := add(sub(subjectEnd, searchLength), 1) let h := 0 if iszero(lt(searchLength, 0x20)) { h := keccak256(search, searchLength) } let m := shl(3, sub(0x20, and(searchLength, 0x1f))) let s := mload(search) for {} 1 {} { let t := mload(subject) // Whether the first `searchLength % 32` bytes of // `subject` and `search` matches. if iszero(shr(m, xor(t, s))) { if h { if iszero(eq(keccak256(subject, searchLength), h)) { mstore(result, t) result := add(result, 1) subject := add(subject, 1) if iszero(lt(subject, subjectSearchEnd)) { break } continue } } // Copy the `replacement` one word at a time. for { let o := 0 } 1 {} { mstore(add(result, o), mload(add(replacement, o))) o := add(o, 0x20) if iszero(lt(o, replacementLength)) { break } } result := add(result, replacementLength) subject := add(subject, searchLength) if searchLength { if iszero(lt(subject, subjectSearchEnd)) { break } continue } } mstore(result, t) result := add(result, 1) subject := add(subject, 1) if iszero(lt(subject, subjectSearchEnd)) { break } } } let resultRemainder := result result := add(mload(0x40), 0x20) let k := add(sub(resultRemainder, result), sub(subjectEnd, subject)) // Copy the rest of the string one word at a time. for {} lt(subject, subjectEnd) {} { mstore(resultRemainder, mload(subject)) resultRemainder := add(resultRemainder, 0x20) subject := add(subject, 0x20) } result := sub(result, 0x20) let last := add(add(result, 0x20), k) // Zeroize the slot after the string. mstore(last, 0) mstore(0x40, add(last, 0x20)) // Allocate the memory. mstore(result, k) // Store the length. } } /// @dev Returns the byte index of the first location of `search` in `subject`, /// searching from left to right, starting from `from`. /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found. function indexOf(string memory subject, string memory search, uint256 from) internal pure returns (uint256 result) { /// @solidity memory-safe-assembly assembly { for { let subjectLength := mload(subject) } 1 {} { if iszero(mload(search)) { if iszero(gt(from, subjectLength)) { result := from break } result := subjectLength break } let searchLength := mload(search) let subjectStart := add(subject, 0x20) result := not(0) // Initialize to `NOT_FOUND`. subject := add(subjectStart, from) let end := add(sub(add(subjectStart, subjectLength), searchLength), 1) let m := shl(3, sub(0x20, and(searchLength, 0x1f))) let s := mload(add(search, 0x20)) if iszero(and(lt(subject, end), lt(from, subjectLength))) { break } if iszero(lt(searchLength, 0x20)) { for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} { if iszero(shr(m, xor(mload(subject), s))) { if eq(keccak256(subject, searchLength), h) { result := sub(subject, subjectStart) break } } subject := add(subject, 1) if iszero(lt(subject, end)) { break } } break } for {} 1 {} { if iszero(shr(m, xor(mload(subject), s))) { result := sub(subject, subjectStart) break } subject := add(subject, 1) if iszero(lt(subject, end)) { break } } break } } } /// @dev Returns the byte index of the first location of `search` in `subject`, /// searching from left to right. /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found. function indexOf(string memory subject, string memory search) internal pure returns (uint256 result) { result = indexOf(subject, search, 0); } /// @dev Returns the byte index of the first location of `search` in `subject`, /// searching from right to left, starting from `from`. /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found. function lastIndexOf(string memory subject, string memory search, uint256 from) internal pure returns (uint256 result) { /// @solidity memory-safe-assembly assembly { for {} 1 {} { result := not(0) // Initialize to `NOT_FOUND`. let searchLength := mload(search) if gt(searchLength, mload(subject)) { break } let w := result let fromMax := sub(mload(subject), searchLength) if iszero(gt(fromMax, from)) { from := fromMax } let end := add(add(subject, 0x20), w) subject := add(add(subject, 0x20), from) if iszero(gt(subject, end)) { break } // As this function is not too often used, // we shall simply use keccak256 for smaller bytecode size. for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} { if eq(keccak256(subject, searchLength), h) { result := sub(subject, add(end, 1)) break } subject := add(subject, w) // `sub(subject, 1)`. if iszero(gt(subject, end)) { break } } break } } } /// @dev Returns the byte index of the first location of `search` in `subject`, /// searching from right to left. /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found. function lastIndexOf(string memory subject, string memory search) internal pure returns (uint256 result) { result = lastIndexOf(subject, search, uint256(int256(-1))); } /// @dev Returns true if `search` is found in `subject`, false otherwise. function contains(string memory subject, string memory search) internal pure returns (bool) { return indexOf(subject, search) != NOT_FOUND; } /// @dev Returns whether `subject` starts with `search`. function startsWith(string memory subject, string memory search) internal pure returns (bool result) { /// @solidity memory-safe-assembly assembly { let searchLength := mload(search) // Just using keccak256 directly is actually cheaper. // forgefmt: disable-next-item result := and( iszero(gt(searchLength, mload(subject))), eq( keccak256(add(subject, 0x20), searchLength), keccak256(add(search, 0x20), searchLength) ) ) } } /// @dev Returns whether `subject` ends with `search`. function endsWith(string memory subject, string memory search) internal pure returns (bool result) { /// @solidity memory-safe-assembly assembly { let searchLength := mload(search) let subjectLength := mload(subject) // Whether `search` is not longer than `subject`. let withinRange := iszero(gt(searchLength, subjectLength)) // Just using keccak256 directly is actually cheaper. // forgefmt: disable-next-item result := and( withinRange, eq( keccak256( // `subject + 0x20 + max(subjectLength - searchLength, 0)`. add(add(subject, 0x20), mul(withinRange, sub(subjectLength, searchLength))), searchLength ), keccak256(add(search, 0x20), searchLength) ) ) } } /// @dev Returns `subject` repeated `times`. function repeat(string memory subject, uint256 times) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let subjectLength := mload(subject) if iszero(or(iszero(times), iszero(subjectLength))) { subject := add(subject, 0x20) result := mload(0x40) let output := add(result, 0x20) for {} 1 {} { // Copy the `subject` one word at a time. for { let o := 0 } 1 {} { mstore(add(output, o), mload(add(subject, o))) o := add(o, 0x20) if iszero(lt(o, subjectLength)) { break } } output := add(output, subjectLength) times := sub(times, 1) if iszero(times) { break } } mstore(output, 0) // Zeroize the slot after the string. let resultLength := sub(output, add(result, 0x20)) mstore(result, resultLength) // Store the length. // Allocate the memory. mstore(0x40, add(result, add(resultLength, 0x20))) } } } /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive). /// `start` and `end` are byte offsets. function slice(string memory subject, uint256 start, uint256 end) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let subjectLength := mload(subject) if iszero(gt(subjectLength, end)) { end := subjectLength } if iszero(gt(subjectLength, start)) { start := subjectLength } if lt(start, end) { result := mload(0x40) let resultLength := sub(end, start) mstore(result, resultLength) subject := add(subject, start) let w := not(0x1f) // Copy the `subject` one word at a time, backwards. for { let o := and(add(resultLength, 0x1f), w) } 1 {} { mstore(add(result, o), mload(add(subject, o))) o := add(o, w) // `sub(o, 0x20)`. if iszero(o) { break } } // Zeroize the slot after the string. mstore(add(add(result, 0x20), resultLength), 0) // Allocate memory for the length and the bytes, // rounded up to a multiple of 32. mstore(0x40, add(result, and(add(resultLength, 0x3f), w))) } } } /// @dev Returns a copy of `subject` sliced from `start` to the end of the string. /// `start` is a byte offset. function slice(string memory subject, uint256 start) internal pure returns (string memory result) { result = slice(subject, start, uint256(int256(-1))); } /// @dev Returns all the indices of `search` in `subject`. /// The indices are byte offsets. function indicesOf(string memory subject, string memory search) internal pure returns (uint256[] memory result) { /// @solidity memory-safe-assembly assembly { let subjectLength := mload(subject) let searchLength := mload(search) if iszero(gt(searchLength, subjectLength)) { subject := add(subject, 0x20) search := add(search, 0x20) result := add(mload(0x40), 0x20) let subjectStart := subject let subjectSearchEnd := add(sub(add(subject, subjectLength), searchLength), 1) let h := 0 if iszero(lt(searchLength, 0x20)) { h := keccak256(search, searchLength) } let m := shl(3, sub(0x20, and(searchLength, 0x1f))) let s := mload(search) for {} 1 {} { let t := mload(subject) // Whether the first `searchLength % 32` bytes of // `subject` and `search` matches. if iszero(shr(m, xor(t, s))) { if h { if iszero(eq(keccak256(subject, searchLength), h)) { subject := add(subject, 1) if iszero(lt(subject, subjectSearchEnd)) { break } continue } } // Append to `result`. mstore(result, sub(subject, subjectStart)) result := add(result, 0x20) // Advance `subject` by `searchLength`. subject := add(subject, searchLength) if searchLength { if iszero(lt(subject, subjectSearchEnd)) { break } continue } } subject := add(subject, 1) if iszero(lt(subject, subjectSearchEnd)) { break } } let resultEnd := result // Assign `result` to the free memory pointer. result := mload(0x40) // Store the length of `result`. mstore(result, shr(5, sub(resultEnd, add(result, 0x20)))) // Allocate memory for result. // We allocate one more word, so this array can be recycled for {split}. mstore(0x40, add(resultEnd, 0x20)) } } } /// @dev Returns a arrays of strings based on the `delimiter` inside of the `subject` string. function split(string memory subject, string memory delimiter) internal pure returns (string[] memory result) { uint256[] memory indices = indicesOf(subject, delimiter); /// @solidity memory-safe-assembly assembly { let w := not(0x1f) let indexPtr := add(indices, 0x20) let indicesEnd := add(indexPtr, shl(5, add(mload(indices), 1))) mstore(add(indicesEnd, w), mload(subject)) mstore(indices, add(mload(indices), 1)) let prevIndex := 0 for {} 1 {} { let index := mload(indexPtr) mstore(indexPtr, 0x60) if iszero(eq(index, prevIndex)) { let element := mload(0x40) let elementLength := sub(index, prevIndex) mstore(element, elementLength) // Copy the `subject` one word at a time, backwards. for { let o := and(add(elementLength, 0x1f), w) } 1 {} { mstore(add(element, o), mload(add(add(subject, prevIndex), o))) o := add(o, w) // `sub(o, 0x20)`. if iszero(o) { break } } // Zeroize the slot after the string. mstore(add(add(element, 0x20), elementLength), 0) // Allocate memory for the length and the bytes, // rounded up to a multiple of 32. mstore(0x40, add(element, and(add(elementLength, 0x3f), w))) // Store the `element` into the array. mstore(indexPtr, element) } prevIndex := add(index, mload(delimiter)) indexPtr := add(indexPtr, 0x20) if iszero(lt(indexPtr, indicesEnd)) { break } } result := indices if iszero(mload(delimiter)) { result := add(indices, 0x20) mstore(result, sub(mload(indices), 2)) } } } /// @dev Returns a concatenated string of `a` and `b`. /// Cheaper than `string.concat()` and does not de-align the free memory pointer. function concat(string memory a, string memory b) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let w := not(0x1f) result := mload(0x40) let aLength := mload(a) // Copy `a` one word at a time, backwards. for { let o := and(add(aLength, 0x20), w) } 1 {} { mstore(add(result, o), mload(add(a, o))) o := add(o, w) // `sub(o, 0x20)`. if iszero(o) { break } } let bLength := mload(b) let output := add(result, aLength) // Copy `b` one word at a time, backwards. for { let o := and(add(bLength, 0x20), w) } 1 {} { mstore(add(output, o), mload(add(b, o))) o := add(o, w) // `sub(o, 0x20)`. if iszero(o) { break } } let totalLength := add(aLength, bLength) let last := add(add(result, 0x20), totalLength) // Zeroize the slot after the string. mstore(last, 0) // Stores the length. mstore(result, totalLength) // Allocate memory for the length and the bytes, // rounded up to a multiple of 32. mstore(0x40, and(add(last, 0x1f), w)) } } /// @dev Returns a copy of the string in either lowercase or UPPERCASE. /// WARNING! This function is only compatible with 7-bit ASCII strings. function toCase(string memory subject, bool toUpper) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let length := mload(subject) if length { result := add(mload(0x40), 0x20) subject := add(subject, 1) let flags := shl(add(70, shl(5, toUpper)), 0x3ffffff) let w := not(0) for { let o := length } 1 {} { o := add(o, w) let b := and(0xff, mload(add(subject, o))) mstore8(add(result, o), xor(b, and(shr(b, flags), 0x20))) if iszero(o) { break } } result := mload(0x40) mstore(result, length) // Store the length. let last := add(add(result, 0x20), length) mstore(last, 0) // Zeroize the slot after the string. mstore(0x40, add(last, 0x20)) // Allocate the memory. } } } /// @dev Returns a string from a small bytes32 string. /// `s` must be null-terminated, or behavior will be undefined. function fromSmallString(bytes32 s) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { result := mload(0x40) let n := 0 for {} byte(n, s) { n := add(n, 1) } {} // Scan for '\0'. mstore(result, n) let o := add(result, 0x20) mstore(o, s) mstore(add(o, n), 0) mstore(0x40, add(result, 0x40)) } } /// @dev Returns the small string, with all bytes after the first null byte zeroized. function normalizeSmallString(bytes32 s) internal pure returns (bytes32 result) { /// @solidity memory-safe-assembly assembly { for {} byte(result, s) { result := add(result, 1) } {} // Scan for '\0'. mstore(0x00, s) mstore(result, 0x00) result := mload(0x00) } } /// @dev Returns the string as a normalized null-terminated small string. function toSmallString(string memory s) internal pure returns (bytes32 result) { /// @solidity memory-safe-assembly assembly { result := mload(s) if iszero(lt(result, 33)) { mstore(0x00, 0xec92f9a3) // `TooBigForSmallString()`. revert(0x1c, 0x04) } result := shl(shl(3, sub(32, result)), mload(add(s, result))) } } /// @dev Returns a lowercased copy of the string. /// WARNING! This function is only compatible with 7-bit ASCII strings. function lower(string memory subject) internal pure returns (string memory result) { result = toCase(subject, false); } /// @dev Returns an UPPERCASED copy of the string. /// WARNING! This function is only compatible with 7-bit ASCII strings. function upper(string memory subject) internal pure returns (string memory result) { result = toCase(subject, true); } /// @dev Escapes the string to be used within HTML tags. function escapeHTML(string memory s) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let end := add(s, mload(s)) result := add(mload(0x40), 0x20) // Store the bytes of the packed offsets and strides into the scratch space. // `packed = (stride << 5) | offset`. Max offset is 20. Max stride is 6. mstore(0x1f, 0x900094) mstore(0x08, 0xc0000000a6ab) // Store ""&'<>" into the scratch space. mstore(0x00, shl(64, 0x2671756f743b26616d703b262333393b266c743b2667743b)) for {} iszero(eq(s, end)) {} { s := add(s, 1) let c := and(mload(s), 0xff) // Not in `["\"","'","&","<",">"]`. if iszero(and(shl(c, 1), 0x500000c400000000)) { mstore8(result, c) result := add(result, 1) continue } let t := shr(248, mload(c)) mstore(result, mload(and(t, 0x1f))) result := add(result, shr(5, t)) } let last := result mstore(last, 0) // Zeroize the slot after the string. result := mload(0x40) mstore(result, sub(last, add(result, 0x20))) // Store the length. mstore(0x40, add(last, 0x20)) // Allocate the memory. } } /// @dev Escapes the string to be used within double-quotes in a JSON. /// If `addDoubleQuotes` is true, the result will be enclosed in double-quotes. function escapeJSON(string memory s, bool addDoubleQuotes) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let end := add(s, mload(s)) result := add(mload(0x40), 0x20) if addDoubleQuotes { mstore8(result, 34) result := add(1, result) } // Store "\\u0000" in scratch space. // Store "0123456789abcdef" in scratch space. // Also, store `{0x08:"b", 0x09:"t", 0x0a:"n", 0x0c:"f", 0x0d:"r"}`. // into the scratch space. mstore(0x15, 0x5c75303030303031323334353637383961626364656662746e006672) // Bitmask for detecting `["\"","\\"]`. let e := or(shl(0x22, 1), shl(0x5c, 1)) for {} iszero(eq(s, end)) {} { s := add(s, 1) let c := and(mload(s), 0xff) if iszero(lt(c, 0x20)) { if iszero(and(shl(c, 1), e)) { // Not in `["\"","\\"]`. mstore8(result, c) result := add(result, 1) continue } mstore8(result, 0x5c) // "\\". mstore8(add(result, 1), c) result := add(result, 2) continue } if iszero(and(shl(c, 1), 0x3700)) { // Not in `["\b","\t","\n","\f","\d"]`. mstore8(0x1d, mload(shr(4, c))) // Hex value. mstore8(0x1e, mload(and(c, 15))) // Hex value. mstore(result, mload(0x19)) // "\\u00XX". result := add(result, 6) continue } mstore8(result, 0x5c) // "\\". mstore8(add(result, 1), mload(add(c, 8))) result := add(result, 2) } if addDoubleQuotes { mstore8(result, 34) result := add(1, result) } let last := result mstore(last, 0) // Zeroize the slot after the string. result := mload(0x40) mstore(result, sub(last, add(result, 0x20))) // Store the length. mstore(0x40, add(last, 0x20)) // Allocate the memory. } } /// @dev Escapes the string to be used within double-quotes in a JSON. function escapeJSON(string memory s) internal pure returns (string memory result) { result = escapeJSON(s, false); } /// @dev Returns whether `a` equals `b`. function eq(string memory a, string memory b) internal pure returns (bool result) { /// @solidity memory-safe-assembly assembly { result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b))) } } /// @dev Returns whether `a` equals `b`. For small strings up to 32 bytes. /// `b` must be null-terminated and normalized, or behavior will be undefined. /// See: `normalizeSmallString`. function eqs(string memory a, bytes32 b) internal pure returns (bool result) { /// @solidity memory-safe-assembly assembly { // These should be evaluated on compile time, as far as possible. let x := and(b, add(not(b), 1)) let r := or(shl(8, iszero(b)), shl(7, iszero(iszero(shr(128, x))))) r := or(r, shl(6, iszero(iszero(shr(64, 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)))) result := gt(eq(mload(a), sub(32, shr(3, r))), shr(r, xor(b, mload(add(a, 0x20))))) } } /// @dev Packs a single string with its length into a single word. /// Returns `bytes32(0)` if the length is zero or greater than 31. function packOne(string memory a) internal pure returns (bytes32 result) { /// @solidity memory-safe-assembly assembly { // We don't need to zero right pad the string, // since this is our own custom non-standard packing scheme. result := mul( // Load the length and the bytes. mload(add(a, 0x1f)), // `length != 0 && length < 32`. Abuses underflow. // Assumes that the length is valid and within the block gas limit. lt(sub(mload(a), 1), 0x1f) ) } } /// @dev Unpacks a string packed using {packOne}. /// Returns the empty string if `packed` is `bytes32(0)`. /// If `packed` is not an output of {packOne}, the output behavior is undefined. function unpackOne(bytes32 packed) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { // Grab the free memory pointer. result := mload(0x40) // Allocate 2 words (1 for the length, 1 for the bytes). mstore(0x40, add(result, 0x40)) // Zeroize the length slot. mstore(result, 0) // Store the length and bytes. mstore(add(result, 0x1f), packed) // Right pad with zeroes. mstore(add(add(result, 0x20), mload(result)), 0) } } /// @dev Packs two strings with their lengths into a single word. /// Returns `bytes32(0)` if combined length is zero or greater than 30. function packTwo(string memory a, string memory b) internal pure returns (bytes32 result) { /// @solidity memory-safe-assembly assembly { let aLength := mload(a) // We don't need to zero right pad the strings, // since this is our own custom non-standard packing scheme. result := mul( // Load the length and the bytes of `a` and `b`. or( shl(shl(3, sub(0x1f, aLength)), mload(add(a, aLength))), mload(sub(add(b, 0x1e), aLength)) ), // `totalLength != 0 && totalLength < 31`. Abuses underflow. // Assumes that the lengths are valid and within the block gas limit. lt(sub(add(aLength, mload(b)), 1), 0x1e) ) } } /// @dev Unpacks strings packed using {packTwo}. /// Returns the empty strings if `packed` is `bytes32(0)`. /// If `packed` is not an output of {packTwo}, the output behavior is undefined. function unpackTwo(bytes32 packed) internal pure returns (string memory resultA, string memory resultB) { /// @solidity memory-safe-assembly assembly { // Grab the free memory pointer. resultA := mload(0x40) resultB := add(resultA, 0x40) // Allocate 2 words for each string (1 for the length, 1 for the byte). Total 4 words. mstore(0x40, add(resultB, 0x40)) // Zeroize the length slots. mstore(resultA, 0) mstore(resultB, 0) // Store the lengths and bytes. mstore(add(resultA, 0x1f), packed) mstore(add(resultB, 0x1f), mload(add(add(resultA, 0x20), mload(resultA)))) // Right pad with zeroes. mstore(add(add(resultA, 0x20), mload(resultA)), 0) mstore(add(add(resultB, 0x20), mload(resultB)), 0) } } /// @dev Directly returns `a` without copying. function directReturn(string memory a) internal pure { assembly { // Assumes that the string does not start from the scratch space. let retStart := sub(a, 0x20) let retSize := add(mload(a), 0x40) // Right pad with zeroes. Just in case the string is produced // by a method that doesn't zero right pad. mstore(add(retStart, retSize), 0) // Store the return offset. mstore(retStart, 0x20) // End the transaction, returning the string. return(retStart, retSize) } } }
{ "remappings": [ "forge-std/=lib/forge-std/src/", "@openzeppelin/=lib/openzeppelin-contracts/", "ERC721A/=lib/ERC721A/contracts/", "solady/=lib/solady/src/", "soladytest/=lib/solady/test/", "sol-json/=lib/sol-json/src/", "ds-test/=lib/forge-std/lib/ds-test/src/", "solmate/=lib/sol-json/lib/solady/lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "evmVersion": "paris", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"stashFactory","type":"address"},{"internalType":"address","name":"cryptoPunks","type":"address"},{"internalType":"address","name":"legacyWrapper","type":"address"},{"internalType":"address","name":"_punksMetadata","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountBalanceOverflow","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"NotOwnerNorApproved","type":"error"},{"inputs":[],"name":"NotPunkOwner","type":"error"},{"inputs":[],"name":"PunkIsOwned","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","type":"error"},{"inputs":[],"name":"TokenDoesNotExist","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"account","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":"isApproved","type":"bool"}],"name":"ApprovalForAll","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":[],"name":"PUNKS_DATA","outputs":[{"internalType":"contract ICryptoPunksData","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"licensingTerms","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"punkIndexes","type":"uint256[]"}],"name":"migrateLegacyWrappedPunks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"punkProxyForUser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"punkIndex","type":"uint256"}],"name":"rescuePunk","outputs":[],"stateMutability":"nonpayable","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":"payable","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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"isApproved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"punkIndex","type":"uint256"}],"name":"unwrapPunk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"punkIndexes","type":"uint256[]"}],"name":"unwrapPunkBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"punkIndex","type":"uint256"}],"name":"wrapPunk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"punkIndexes","type":"uint256[]"}],"name":"wrapPunkBatch","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101006040523480156200001257600080fd5b50604051620026dd380380620026dd833981016040819052620000359162000076565b6001600160a01b0390811660805292831660a05290821660c0521660e052620000d3565b80516001600160a01b03811681146200007157600080fd5b919050565b600080600080608085870312156200008d57600080fd5b620000988562000059565b9350620000a86020860162000059565b9250620000b86040860162000059565b9150620000c86060860162000059565b905092959194509250565b60805160a05160c05160e0516125916200014c60003960008181610cc60152610d360152600081816105c101528181610c100152610f600152600081816104e8015281816108b40152818161094901528181610a3c0152610ad10152600081816102ab015281816112c301526113ac01526125916000f3fe60806040526004361061014b5760003560e01c806390aaf2ff116100b6578063b88d4fde1161006f578063b88d4fde14610408578063c87b56dd1461041b578063cbc307021461043b578063df53b5c11461045b578063e4a5016d14610470578063e985e9c51461049057600080fd5b806390aaf2ff1461033a57806395d89b411461035a5780639e88cf42146103885780639f8f573f146103a8578063a14aad90146103c8578063a22cb465146103e857600080fd5b806323b872dd1161010857806323b872dd1461027357806342842e0e146102865780634ed9a045146102995780636352211e146102cd57806370a08231146102ed5780638462151c1461030d57600080fd5b806301ffc9a71461015057806306fdde03146101a257806307f2a9b1146101e3578063081812fc1461021b578063095ea7b31461023b57806318160ddd14610250575b600080fd5b34801561015c57600080fd5b5061018d61016b366004611eaa565b6301ffc9a760e09190911c9081146380ac58cd821417635b5e139f9091141790565b60405190151581526020015b60405180910390f35b3480156101ae57600080fd5b5060408051808201909152600f81526e43727970746f50756e6b732037323160881b60208201525b6040516101999190611ef8565b3480156101ef57600080fd5b506102036101fe366004611f43565b6104c6565b6040516001600160a01b039091168152602001610199565b34801561022757600080fd5b50610203610236366004611f60565b61055b565b61024e610249366004611f79565b61059a565b005b34801561025c57600080fd5b506102656105a9565b604051908152602001610199565b61024e610281366004611fa5565b610639565b61024e610294366004611fa5565b610750565b3480156102a557600080fd5b506102037f000000000000000000000000000000000000000000000000000000000000000081565b3480156102d957600080fd5b506102036102e8366004611f60565b61077d565b3480156102f957600080fd5b50610265610308366004611f43565b6107a2565b34801561031957600080fd5b5061032d610328366004611f43565b6107dd565b6040516101999190611fe6565b34801561034657600080fd5b5061024e610355366004611f60565b61089c565b34801561036657600080fd5b50604080518082019091526005815264cfbe37323160d81b60208201526101d6565b34801561039457600080fd5b5061024e6103a336600461202a565b610a24565b3480156103b457600080fd5b5061024e6103c3366004611f60565b610bea565b3480156103d457600080fd5b5061024e6103e336600461202a565b610c70565b3480156103f457600080fd5b5061024e61040336600461209f565b610daf565b61024e6104163660046120dd565b610e05565b34801561042757600080fd5b506101d6610436366004611f60565b610e59565b34801561044757600080fd5b5061024e610456366004611f60565b610eb4565b34801561046757600080fd5b506101d6610ef2565b34801561047c57600080fd5b5061024e61048b36600461202a565b610f12565b34801561049c57600080fd5b5061018d6104ab36600461217c565b601c52670a5a2e7a000000006008526000526030600c205490565b60405163332599d560e01b81526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063332599d590602401602060405180830381865afa158015610531573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061055591906121aa565b92915050565b600081600052673ec412a9852d173d60c11b601c52602060002082018201805460601b6105905763ceea21b66000526004601cfd5b6001015492915050565b6105a5338383610fd1565b5050565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610610573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063491906121c7565b905090565b6000818152673ec412a9852d173d60c11b3317601c52602090208101810180546001600160a01b03948516949384169381169190828614830261069757826106895763ceea21b66000526004601cfd5b63a11481006000526004601cfd5b846106aa5763ea553b346000526004601cfd5b8560005281600101549250823314863314176106d8576030600c20546106d857634b6e7f186000526004601cfd5b82156106e657600082600101555b85851818905550601c600c8181208054600019019055600084905220805460010163ffffffff8116610720576301336cea6000526004601cfd5b90558082847fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600038a45b505050565b61075b838383610639565b813b1561074b5761074b83838360405180602001604052806000815250611072565b6000610788826110fe565b90508061079d5763ceea21b66000526004601cfd5b919050565b6000816107b757638f4eb6046000526004601cfd5b673ec412a9852d173d60c11b601c528160005263ffffffff601c600c2054169050919050565b60606000806107eb846107a2565b905060008167ffffffffffffffff811115610808576108086121e0565b604051908082528060200260200182016040528015610831578160200160208202803683370190505b50905060005b828414610893576000610849826110fe565b9050866001600160a01b0316816001600160a01b03160361088a578183868060010197508151811061087d5761087d6121f6565b6020026020010181815250505b50600101610837565b50949350505050565b60405163332599d560e01b81523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063332599d590602401602060405180830381865afa158015610903573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092791906121aa565b9050803b60008190036109c057604051631d85641960e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631d856419906024016020604051808303816000875af115801561099a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109be91906121aa565b505b6040516390aaf2ff60e01b8152600481018490526001600160a01b038316906390aaf2ff90602401600060405180830381600087803b158015610a0257600080fd5b505af1158015610a16573d6000803e3d6000fd5b5050505061074b3384611126565b60405163332599d560e01b81523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063332599d590602401602060405180830381865afa158015610a8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aaf91906121aa565b9050803b6000819003610b4857604051631d85641960e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631d856419906024016020604051808303816000875af1158015610b22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4691906121aa565b505b60005b83811015610be3576000858583818110610b6757610b676121f6565b905060200201359050836001600160a01b03166390aaf2ff826040518263ffffffff1660e01b8152600401610b9e91815260200190565b600060405180830381600087803b158015610bb857600080fd5b505af1158015610bcc573d6000803e3d6000fd5b50505050610bda3382611126565b50600101610b4b565b5050505050565b610bf433826111d4565b6040516322dca8bb60e21b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690638b72a2ec90604401600060405180830381600087803b158015610c5c57600080fd5b505af1158015610be3573d6000803e3d6000fd5b60005b8181101561074b576000838383818110610c8f57610c8f6121f6565b6040516323b872dd60e01b815233600482015230602482015260209091029290920135604483018190529250506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906323b872dd90606401600060405180830381600087803b158015610d0a57600080fd5b505af1158015610d1e573d6000803e3d6000fd5b5050604051630852cd8d60e31b8152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692506342966c689150602401600060405180830381600087803b158015610d8457600080fd5b505af1158015610d98573d6000803e3d6000fd5b50505050610da63382611126565b50600101610c73565b801515905081601c52670a5a2e7a0000000060085233600052806030600c2055806000528160601b60601c337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160206000a35050565b610e10858585610639565b833b15610be357610be385858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061107292505050565b60606127108210610e7d5760405163677510db60e11b815260040160405180910390fd5b610e8e610e89836112a2565b6114d3565b604051602001610e9e919061220c565b6040516020818303038152906040529050919050565b6000818152673ec412a9852d173d60c11b601c5260209020810181015460601b15610bf4576040516302a6afa960e11b815260040160405180910390fd5b606060405180606001604052806025815260200161250660259139905090565b60005b8181101561074b576000838383818110610f3157610f316121f6565b905060200201359050610f4433826111d4565b6040516322dca8bb60e21b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690638b72a2ec90604401600060405180830381600087803b158015610fac57600080fd5b505af1158015610fc0573d6000803e3d6000fd5b505060019093019250610f15915050565b60001960601c828116925083811693508160005283673ec412a9852d173d60c11b17601c52602060002082018201805482169150816110185763ceea21b66000526004601cfd5b81851485151761103e57816000526030600c205461103e57634b6e7f186000526004601cfd5b6001018390558183827f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600038a450505050565b60405163150b7a028082523360208301528560601b60601c604083015283606083015260808083015282518060a084015280156110b9578060c08401826020870160045afa505b60208360a48301601c860160008a5af16110dc573d156110dc573d6000843e3d83fd5b508060e01b8251146110f65763d1a57ed66000526004601cfd5b505050505050565b6000818152673ec412a9852d173d60c11b601c5260209020810101546001600160a01b031690565b6001600160a01b0390911690816111455763ea553b346000526004601cfd5b80600052673ec412a9852d173d60c11b601c5260206000208101810180548060601b1561117a5763c991cbb16000526004601cfd5b831790556000829052601c600c20805460010163ffffffff81166111a6576301336cea6000526004601cfd5b9055808260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8138a45050565b60006111df8261077d565b90505060008181526001600160a01b03928316673ec412a9852d173d60c11b8117601c5260209091208201820180549193821691826112265763ceea21b66000526004601cfd5b82600052816001015480861484871417861517611255576030600c205461125557634b6e7f186000526004601cfd5b801561126357600083600101555b5082189055601c600c208054600019019055816000827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8238a4505050565b6040516374beb04760e01b815261ffff8216600482015260609082906000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906374beb04790602401600060405180830381865afa158015611312573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261133a9190810190612251565b90506113478160186114e1565b9050611385611359826000604a6114f7565b61138060405180606001604052806031815260200161252b6031913961138085604a6114e1565b61155d565b6040516376dfe29760e01b815261ffff841660048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906376dfe29790602401600060405180830381865afa1580156113f3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261141b9190810190612251565b9050611426816115b8565b90506114ca61147960405180604001604052806005815260200164696d61676560d81b815250611455856114d3565b60405160200161146591906122fe565b604051602081830303815290604052611949565b6114a56040518060400160405280600a8152602001696174747269627574657360b01b81525084611985565b6040516020016114b6929190612343565b6040516020818303038152906040526119a2565b95945050505050565b6060610555826000806119b5565b60606114f083836000196114f7565b9392505050565b60608351828111611506578092505b838111611511578093505b50818310156114f0575060405182820380825293830193601f19601f820181165b86810151848201528101806115325750600083830160200152603f9091011681016040529392505050565b6040518251601f19906020810182165b858101518482015282018061156d575083518184018360208301165b86810151828201528401806115895750506000910183810160208101929092528352603f011660405292915050565b606060006115e08360405180604001604052806002815260200161016160f51b815250611a9d565b90506000816000815181106115f7576115f76121f6565b6020026020010151600081518110611611576116116121f6565b01602001516001600160f81b03191690506000604d60f81b8214806116435750602360f91b6001600160f81b03198316145b9050606080821561174b57845161165b906002612395565b67ffffffffffffffff811115611673576116736121e0565b6040519080825280602002602001820160405280156116a657816020015b60608152602001906001900390816116915790505b5091506116e6856000815181106116bf576116bf6121f6565b6020026020010151604051806040016040528060018152602001600160fd1b815250611a9d565b9050611728604051806040016040528060048152602001635479706560e01b8152508260008151811061171b5761171b6121f6565b6020026020010151611b48565b8260008151811061173b5761173b6121f6565b60200260200101819052506117f8565b8451611758906001612395565b67ffffffffffffffff811115611770576117706121e0565b6040519080825280602002602001820160405280156117a357816020015b606081526020019060019003908161178e5790505b5091506117d9604051806040016040528060048152602001635479706560e01b8152508660008151811061171b5761171b6121f6565b826000815181106117ec576117ec6121f6565b60200260200101819052505b60006001865161180891906123a8565b60408051808201909152600981526841747472696275746560b81b602082015290915060015b87518110156118725761184d8289838151811061171b5761171b6121f6565b85828151811061185f5761185f6121f6565b602090810291909101015260010161182e565b506118ac6040518060400160405280600f81526020016e105d1d1c9a589d5d194810dbdd5b9d608a1b8152506118a784611ba0565b611b48565b848851815181106118bf576118bf6121f6565b602002602001018190525084156119335761190860405180604001604052806009815260200168536b696e20546f6e6560b81b8152508460018151811061171b5761171b6121f6565b84885160016119179190612395565b81518110611927576119276121f6565b60200260200101819052505b61193c84611be4565b9998505050505050505050565b606061195483611bf7565b61195d83611bf7565b60405160200161196e9291906123bb565b604051602081830303815290604052905092915050565b606061199083611bf7565b8260405160200161196e92919061240f565b606081604051602001610e9e919061245a565b606083518015611a95576003600282010460021b60405192507f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f526106708515027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f18603f52602083018181015b6003880197508751603f8160121c1651600053603f81600c1c1651600153603f8160061c1651600253603f811651600353506000518252600482019150808210611a2557602001604052613d3d60f01b600384066002048083039190915260008615159091029182900352900382525b509392505050565b60606000611aab8484611c04565b9050601f1960208201600183510160051b81018651838201526001845101845260005b825160608452818114611b135760405182820380825286601f8201165b8b850181015183820152870180611aeb5750600082820160200152603f018616810160405284525b875160209490940193019050818310611ace57505050508091508251611b4157602081019150600281510382525b5092915050565b60606114f0611b796040518060400160405280600a81526020016974726169745f7479706560b01b81525085611949565b6114a56040518060400160405280600581526020016476616c756560d81b81525085611949565b60606080604051019050602081016040526000815280600019835b928101926030600a8206018453600a900480611bbb575050819003601f19909101908152919050565b6060610555611bf283611cd3565b611cf8565b6060610555826000611d0b565b606082518251818111611ccb576020850194506020840193506020604051019250846001828488010301600060208410611c3d57508286205b601f841660200360031b87515b8951818118831c611c9f578315611c7d5783878c2014611c7d5760018b019a50848b10611c775750611cae565b50611c4a565b858b038952998601996020909801978615611c9f57848b10611c775750611cae565b5060018a019950838a10611c4a575b505060408051601f198189030160051c8152602090970190525050505b505092915050565b606061055582604051806040016040528060018152602001600b60fa1b815250611e13565b606081604051602001610e9e919061248e565b81516040516020019083018215611d2757602282538160010191505b7b5c75303030303031323334353637383961626364656662746e0066726015526b1000000000000004000000005b818514611de55760018501945060ff85511660208110611d9e57816001821b16611d885780845360018401935050611d55565b605c845380600185015360028401935050611d55565b6137006001821b16611dcb578060041c51601d53600f811651601e53601951845260068401935050611d55565b605c84536008810151600185015350600283019250611d55565b50508115611df557602281536001015b6000815260408051601f198184030181526020909201905292915050565b60608251600003611e335750604080516020810190915260008152610555565b600083600081518110611e4857611e486121f6565b602002602001015190506000600190505b8451811015611a95578184868381518110611e7657611e766121f6565b6020026020010151604051602001611e90939291906124c2565b60408051601f198184030181529190529150600101611e59565b600060208284031215611ebc57600080fd5b81356001600160e01b0319811681146114f057600080fd5b60005b83811015611eef578181015183820152602001611ed7565b50506000910152565b6020815260008251806020840152611f17816040850160208701611ed4565b601f01601f19169190910160400192915050565b6001600160a01b0381168114611f4057600080fd5b50565b600060208284031215611f5557600080fd5b81356114f081611f2b565b600060208284031215611f7257600080fd5b5035919050565b60008060408385031215611f8c57600080fd5b8235611f9781611f2b565b946020939093013593505050565b600080600060608486031215611fba57600080fd5b8335611fc581611f2b565b92506020840135611fd581611f2b565b929592945050506040919091013590565b6020808252825182820181905260009190848201906040850190845b8181101561201e57835183529284019291840191600101612002565b50909695505050505050565b6000806020838503121561203d57600080fd5b823567ffffffffffffffff8082111561205557600080fd5b818501915085601f83011261206957600080fd5b81358181111561207857600080fd5b8660208260051b850101111561208d57600080fd5b60209290920196919550909350505050565b600080604083850312156120b257600080fd5b82356120bd81611f2b565b9150602083013580151581146120d257600080fd5b809150509250929050565b6000806000806000608086880312156120f557600080fd5b853561210081611f2b565b9450602086013561211081611f2b565b935060408601359250606086013567ffffffffffffffff8082111561213457600080fd5b818801915088601f83011261214857600080fd5b81358181111561215757600080fd5b89602082850101111561216957600080fd5b9699959850939650602001949392505050565b6000806040838503121561218f57600080fd5b823561219a81611f2b565b915060208301356120d281611f2b565b6000602082840312156121bc57600080fd5b81516114f081611f2b565b6000602082840312156121d957600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161224481601d850160208701611ed4565b91909101601d0192915050565b60006020828403121561226357600080fd5b815167ffffffffffffffff8082111561227b57600080fd5b818401915084601f83011261228f57600080fd5b8151818111156122a1576122a16121e0565b604051601f8201601f19908116603f011681019083821181831017156122c9576122c96121e0565b816040528281528760208487010111156122e257600080fd5b6122f3836020830160208801611ed4565b979650505050505050565b7f646174613a696d6167652f7376672b786d6c3b6261736536342c00000000000081526000825161233681601a850160208701611ed4565b91909101601a0192915050565b60008351612355818460208801611ed4565b600b60fa1b9083019081528351612373816001840160208801611ed4565b01600101949350505050565b634e487b7160e01b600052601160045260246000fd5b808201808211156105555761055561237f565b818103818111156105555761055561237f565b6000601160f91b80835284516123d8816001860160208901611ed4565b62111d1160e91b60019185019182015284516123fb816004840160208901611ed4565b016004810191909152600501949350505050565b601160f91b8152825160009061242c816001850160208801611ed4565b61111d60f11b600191840191820152835161244e816003840160208801611ed4565b01600301949350505050565b607b60f81b815260008251612476816001850160208701611ed4565b607d60f81b6001939091019283015250600201919050565b605b60f81b8152600082516124aa816001850160208701611ed4565b605d60f81b6001939091019283015250600201919050565b600084516124d4818460208901611ed4565b8451908301906124e8818360208901611ed4565b84519101906124fb818360208801611ed4565b019594505050505056fe68747470733a2f2f6c6963656e73657465726d732e63727970746f70756e6b732e6170702f3c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d2223363641363730222f3ea2646970667358221220ec69e097faa40b1dd7edff68a2f5c690527e70894098594d1c74088f56d40ba064736f6c63430008170033000000000000000000000000000000000000a6fa31f5fc51c1640aac76866750000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb000000000000000000000000b7f7f6c52f2e2fdb1963eab30438024864c313f600000000000000000000000016f5a35647d6f03d5d3da7b35409d65ba03af3b2
Deployed Bytecode
0x60806040526004361061014b5760003560e01c806390aaf2ff116100b6578063b88d4fde1161006f578063b88d4fde14610408578063c87b56dd1461041b578063cbc307021461043b578063df53b5c11461045b578063e4a5016d14610470578063e985e9c51461049057600080fd5b806390aaf2ff1461033a57806395d89b411461035a5780639e88cf42146103885780639f8f573f146103a8578063a14aad90146103c8578063a22cb465146103e857600080fd5b806323b872dd1161010857806323b872dd1461027357806342842e0e146102865780634ed9a045146102995780636352211e146102cd57806370a08231146102ed5780638462151c1461030d57600080fd5b806301ffc9a71461015057806306fdde03146101a257806307f2a9b1146101e3578063081812fc1461021b578063095ea7b31461023b57806318160ddd14610250575b600080fd5b34801561015c57600080fd5b5061018d61016b366004611eaa565b6301ffc9a760e09190911c9081146380ac58cd821417635b5e139f9091141790565b60405190151581526020015b60405180910390f35b3480156101ae57600080fd5b5060408051808201909152600f81526e43727970746f50756e6b732037323160881b60208201525b6040516101999190611ef8565b3480156101ef57600080fd5b506102036101fe366004611f43565b6104c6565b6040516001600160a01b039091168152602001610199565b34801561022757600080fd5b50610203610236366004611f60565b61055b565b61024e610249366004611f79565b61059a565b005b34801561025c57600080fd5b506102656105a9565b604051908152602001610199565b61024e610281366004611fa5565b610639565b61024e610294366004611fa5565b610750565b3480156102a557600080fd5b506102037f00000000000000000000000016f5a35647d6f03d5d3da7b35409d65ba03af3b281565b3480156102d957600080fd5b506102036102e8366004611f60565b61077d565b3480156102f957600080fd5b50610265610308366004611f43565b6107a2565b34801561031957600080fd5b5061032d610328366004611f43565b6107dd565b6040516101999190611fe6565b34801561034657600080fd5b5061024e610355366004611f60565b61089c565b34801561036657600080fd5b50604080518082019091526005815264cfbe37323160d81b60208201526101d6565b34801561039457600080fd5b5061024e6103a336600461202a565b610a24565b3480156103b457600080fd5b5061024e6103c3366004611f60565b610bea565b3480156103d457600080fd5b5061024e6103e336600461202a565b610c70565b3480156103f457600080fd5b5061024e61040336600461209f565b610daf565b61024e6104163660046120dd565b610e05565b34801561042757600080fd5b506101d6610436366004611f60565b610e59565b34801561044757600080fd5b5061024e610456366004611f60565b610eb4565b34801561046757600080fd5b506101d6610ef2565b34801561047c57600080fd5b5061024e61048b36600461202a565b610f12565b34801561049c57600080fd5b5061018d6104ab36600461217c565b601c52670a5a2e7a000000006008526000526030600c205490565b60405163332599d560e01b81526001600160a01b0382811660048301526000917f000000000000000000000000000000000000a6fa31f5fc51c1640aac768667509091169063332599d590602401602060405180830381865afa158015610531573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061055591906121aa565b92915050565b600081600052673ec412a9852d173d60c11b601c52602060002082018201805460601b6105905763ceea21b66000526004601cfd5b6001015492915050565b6105a5338383610fd1565b5050565b6040516370a0823160e01b81523060048201526000907f000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb6001600160a01b0316906370a0823190602401602060405180830381865afa158015610610573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063491906121c7565b905090565b6000818152673ec412a9852d173d60c11b3317601c52602090208101810180546001600160a01b03948516949384169381169190828614830261069757826106895763ceea21b66000526004601cfd5b63a11481006000526004601cfd5b846106aa5763ea553b346000526004601cfd5b8560005281600101549250823314863314176106d8576030600c20546106d857634b6e7f186000526004601cfd5b82156106e657600082600101555b85851818905550601c600c8181208054600019019055600084905220805460010163ffffffff8116610720576301336cea6000526004601cfd5b90558082847fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600038a45b505050565b61075b838383610639565b813b1561074b5761074b83838360405180602001604052806000815250611072565b6000610788826110fe565b90508061079d5763ceea21b66000526004601cfd5b919050565b6000816107b757638f4eb6046000526004601cfd5b673ec412a9852d173d60c11b601c528160005263ffffffff601c600c2054169050919050565b60606000806107eb846107a2565b905060008167ffffffffffffffff811115610808576108086121e0565b604051908082528060200260200182016040528015610831578160200160208202803683370190505b50905060005b828414610893576000610849826110fe565b9050866001600160a01b0316816001600160a01b03160361088a578183868060010197508151811061087d5761087d6121f6565b6020026020010181815250505b50600101610837565b50949350505050565b60405163332599d560e01b81523360048201526000907f000000000000000000000000000000000000a6fa31f5fc51c1640aac768667506001600160a01b03169063332599d590602401602060405180830381865afa158015610903573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092791906121aa565b9050803b60008190036109c057604051631d85641960e01b81523360048201527f000000000000000000000000000000000000a6fa31f5fc51c1640aac768667506001600160a01b031690631d856419906024016020604051808303816000875af115801561099a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109be91906121aa565b505b6040516390aaf2ff60e01b8152600481018490526001600160a01b038316906390aaf2ff90602401600060405180830381600087803b158015610a0257600080fd5b505af1158015610a16573d6000803e3d6000fd5b5050505061074b3384611126565b60405163332599d560e01b81523360048201526000907f000000000000000000000000000000000000a6fa31f5fc51c1640aac768667506001600160a01b03169063332599d590602401602060405180830381865afa158015610a8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aaf91906121aa565b9050803b6000819003610b4857604051631d85641960e01b81523360048201527f000000000000000000000000000000000000a6fa31f5fc51c1640aac768667506001600160a01b031690631d856419906024016020604051808303816000875af1158015610b22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4691906121aa565b505b60005b83811015610be3576000858583818110610b6757610b676121f6565b905060200201359050836001600160a01b03166390aaf2ff826040518263ffffffff1660e01b8152600401610b9e91815260200190565b600060405180830381600087803b158015610bb857600080fd5b505af1158015610bcc573d6000803e3d6000fd5b50505050610bda3382611126565b50600101610b4b565b5050505050565b610bf433826111d4565b6040516322dca8bb60e21b8152336004820152602481018290527f000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb6001600160a01b031690638b72a2ec90604401600060405180830381600087803b158015610c5c57600080fd5b505af1158015610be3573d6000803e3d6000fd5b60005b8181101561074b576000838383818110610c8f57610c8f6121f6565b6040516323b872dd60e01b815233600482015230602482015260209091029290920135604483018190529250506001600160a01b037f000000000000000000000000b7f7f6c52f2e2fdb1963eab30438024864c313f616906323b872dd90606401600060405180830381600087803b158015610d0a57600080fd5b505af1158015610d1e573d6000803e3d6000fd5b5050604051630852cd8d60e31b8152600481018490527f000000000000000000000000b7f7f6c52f2e2fdb1963eab30438024864c313f66001600160a01b031692506342966c689150602401600060405180830381600087803b158015610d8457600080fd5b505af1158015610d98573d6000803e3d6000fd5b50505050610da63382611126565b50600101610c73565b801515905081601c52670a5a2e7a0000000060085233600052806030600c2055806000528160601b60601c337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160206000a35050565b610e10858585610639565b833b15610be357610be385858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061107292505050565b60606127108210610e7d5760405163677510db60e11b815260040160405180910390fd5b610e8e610e89836112a2565b6114d3565b604051602001610e9e919061220c565b6040516020818303038152906040529050919050565b6000818152673ec412a9852d173d60c11b601c5260209020810181015460601b15610bf4576040516302a6afa960e11b815260040160405180910390fd5b606060405180606001604052806025815260200161250660259139905090565b60005b8181101561074b576000838383818110610f3157610f316121f6565b905060200201359050610f4433826111d4565b6040516322dca8bb60e21b8152336004820152602481018290527f000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb6001600160a01b031690638b72a2ec90604401600060405180830381600087803b158015610fac57600080fd5b505af1158015610fc0573d6000803e3d6000fd5b505060019093019250610f15915050565b60001960601c828116925083811693508160005283673ec412a9852d173d60c11b17601c52602060002082018201805482169150816110185763ceea21b66000526004601cfd5b81851485151761103e57816000526030600c205461103e57634b6e7f186000526004601cfd5b6001018390558183827f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600038a450505050565b60405163150b7a028082523360208301528560601b60601c604083015283606083015260808083015282518060a084015280156110b9578060c08401826020870160045afa505b60208360a48301601c860160008a5af16110dc573d156110dc573d6000843e3d83fd5b508060e01b8251146110f65763d1a57ed66000526004601cfd5b505050505050565b6000818152673ec412a9852d173d60c11b601c5260209020810101546001600160a01b031690565b6001600160a01b0390911690816111455763ea553b346000526004601cfd5b80600052673ec412a9852d173d60c11b601c5260206000208101810180548060601b1561117a5763c991cbb16000526004601cfd5b831790556000829052601c600c20805460010163ffffffff81166111a6576301336cea6000526004601cfd5b9055808260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8138a45050565b60006111df8261077d565b90505060008181526001600160a01b03928316673ec412a9852d173d60c11b8117601c5260209091208201820180549193821691826112265763ceea21b66000526004601cfd5b82600052816001015480861484871417861517611255576030600c205461125557634b6e7f186000526004601cfd5b801561126357600083600101555b5082189055601c600c208054600019019055816000827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8238a4505050565b6040516374beb04760e01b815261ffff8216600482015260609082906000907f00000000000000000000000016f5a35647d6f03d5d3da7b35409d65ba03af3b26001600160a01b0316906374beb04790602401600060405180830381865afa158015611312573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261133a9190810190612251565b90506113478160186114e1565b9050611385611359826000604a6114f7565b61138060405180606001604052806031815260200161252b6031913961138085604a6114e1565b61155d565b6040516376dfe29760e01b815261ffff841660048201529091506000906001600160a01b037f00000000000000000000000016f5a35647d6f03d5d3da7b35409d65ba03af3b216906376dfe29790602401600060405180830381865afa1580156113f3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261141b9190810190612251565b9050611426816115b8565b90506114ca61147960405180604001604052806005815260200164696d61676560d81b815250611455856114d3565b60405160200161146591906122fe565b604051602081830303815290604052611949565b6114a56040518060400160405280600a8152602001696174747269627574657360b01b81525084611985565b6040516020016114b6929190612343565b6040516020818303038152906040526119a2565b95945050505050565b6060610555826000806119b5565b60606114f083836000196114f7565b9392505050565b60608351828111611506578092505b838111611511578093505b50818310156114f0575060405182820380825293830193601f19601f820181165b86810151848201528101806115325750600083830160200152603f9091011681016040529392505050565b6040518251601f19906020810182165b858101518482015282018061156d575083518184018360208301165b86810151828201528401806115895750506000910183810160208101929092528352603f011660405292915050565b606060006115e08360405180604001604052806002815260200161016160f51b815250611a9d565b90506000816000815181106115f7576115f76121f6565b6020026020010151600081518110611611576116116121f6565b01602001516001600160f81b03191690506000604d60f81b8214806116435750602360f91b6001600160f81b03198316145b9050606080821561174b57845161165b906002612395565b67ffffffffffffffff811115611673576116736121e0565b6040519080825280602002602001820160405280156116a657816020015b60608152602001906001900390816116915790505b5091506116e6856000815181106116bf576116bf6121f6565b6020026020010151604051806040016040528060018152602001600160fd1b815250611a9d565b9050611728604051806040016040528060048152602001635479706560e01b8152508260008151811061171b5761171b6121f6565b6020026020010151611b48565b8260008151811061173b5761173b6121f6565b60200260200101819052506117f8565b8451611758906001612395565b67ffffffffffffffff811115611770576117706121e0565b6040519080825280602002602001820160405280156117a357816020015b606081526020019060019003908161178e5790505b5091506117d9604051806040016040528060048152602001635479706560e01b8152508660008151811061171b5761171b6121f6565b826000815181106117ec576117ec6121f6565b60200260200101819052505b60006001865161180891906123a8565b60408051808201909152600981526841747472696275746560b81b602082015290915060015b87518110156118725761184d8289838151811061171b5761171b6121f6565b85828151811061185f5761185f6121f6565b602090810291909101015260010161182e565b506118ac6040518060400160405280600f81526020016e105d1d1c9a589d5d194810dbdd5b9d608a1b8152506118a784611ba0565b611b48565b848851815181106118bf576118bf6121f6565b602002602001018190525084156119335761190860405180604001604052806009815260200168536b696e20546f6e6560b81b8152508460018151811061171b5761171b6121f6565b84885160016119179190612395565b81518110611927576119276121f6565b60200260200101819052505b61193c84611be4565b9998505050505050505050565b606061195483611bf7565b61195d83611bf7565b60405160200161196e9291906123bb565b604051602081830303815290604052905092915050565b606061199083611bf7565b8260405160200161196e92919061240f565b606081604051602001610e9e919061245a565b606083518015611a95576003600282010460021b60405192507f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f526106708515027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f18603f52602083018181015b6003880197508751603f8160121c1651600053603f81600c1c1651600153603f8160061c1651600253603f811651600353506000518252600482019150808210611a2557602001604052613d3d60f01b600384066002048083039190915260008615159091029182900352900382525b509392505050565b60606000611aab8484611c04565b9050601f1960208201600183510160051b81018651838201526001845101845260005b825160608452818114611b135760405182820380825286601f8201165b8b850181015183820152870180611aeb5750600082820160200152603f018616810160405284525b875160209490940193019050818310611ace57505050508091508251611b4157602081019150600281510382525b5092915050565b60606114f0611b796040518060400160405280600a81526020016974726169745f7479706560b01b81525085611949565b6114a56040518060400160405280600581526020016476616c756560d81b81525085611949565b60606080604051019050602081016040526000815280600019835b928101926030600a8206018453600a900480611bbb575050819003601f19909101908152919050565b6060610555611bf283611cd3565b611cf8565b6060610555826000611d0b565b606082518251818111611ccb576020850194506020840193506020604051019250846001828488010301600060208410611c3d57508286205b601f841660200360031b87515b8951818118831c611c9f578315611c7d5783878c2014611c7d5760018b019a50848b10611c775750611cae565b50611c4a565b858b038952998601996020909801978615611c9f57848b10611c775750611cae565b5060018a019950838a10611c4a575b505060408051601f198189030160051c8152602090970190525050505b505092915050565b606061055582604051806040016040528060018152602001600b60fa1b815250611e13565b606081604051602001610e9e919061248e565b81516040516020019083018215611d2757602282538160010191505b7b5c75303030303031323334353637383961626364656662746e0066726015526b1000000000000004000000005b818514611de55760018501945060ff85511660208110611d9e57816001821b16611d885780845360018401935050611d55565b605c845380600185015360028401935050611d55565b6137006001821b16611dcb578060041c51601d53600f811651601e53601951845260068401935050611d55565b605c84536008810151600185015350600283019250611d55565b50508115611df557602281536001015b6000815260408051601f198184030181526020909201905292915050565b60608251600003611e335750604080516020810190915260008152610555565b600083600081518110611e4857611e486121f6565b602002602001015190506000600190505b8451811015611a95578184868381518110611e7657611e766121f6565b6020026020010151604051602001611e90939291906124c2565b60408051601f198184030181529190529150600101611e59565b600060208284031215611ebc57600080fd5b81356001600160e01b0319811681146114f057600080fd5b60005b83811015611eef578181015183820152602001611ed7565b50506000910152565b6020815260008251806020840152611f17816040850160208701611ed4565b601f01601f19169190910160400192915050565b6001600160a01b0381168114611f4057600080fd5b50565b600060208284031215611f5557600080fd5b81356114f081611f2b565b600060208284031215611f7257600080fd5b5035919050565b60008060408385031215611f8c57600080fd5b8235611f9781611f2b565b946020939093013593505050565b600080600060608486031215611fba57600080fd5b8335611fc581611f2b565b92506020840135611fd581611f2b565b929592945050506040919091013590565b6020808252825182820181905260009190848201906040850190845b8181101561201e57835183529284019291840191600101612002565b50909695505050505050565b6000806020838503121561203d57600080fd5b823567ffffffffffffffff8082111561205557600080fd5b818501915085601f83011261206957600080fd5b81358181111561207857600080fd5b8660208260051b850101111561208d57600080fd5b60209290920196919550909350505050565b600080604083850312156120b257600080fd5b82356120bd81611f2b565b9150602083013580151581146120d257600080fd5b809150509250929050565b6000806000806000608086880312156120f557600080fd5b853561210081611f2b565b9450602086013561211081611f2b565b935060408601359250606086013567ffffffffffffffff8082111561213457600080fd5b818801915088601f83011261214857600080fd5b81358181111561215757600080fd5b89602082850101111561216957600080fd5b9699959850939650602001949392505050565b6000806040838503121561218f57600080fd5b823561219a81611f2b565b915060208301356120d281611f2b565b6000602082840312156121bc57600080fd5b81516114f081611f2b565b6000602082840312156121d957600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161224481601d850160208701611ed4565b91909101601d0192915050565b60006020828403121561226357600080fd5b815167ffffffffffffffff8082111561227b57600080fd5b818401915084601f83011261228f57600080fd5b8151818111156122a1576122a16121e0565b604051601f8201601f19908116603f011681019083821181831017156122c9576122c96121e0565b816040528281528760208487010111156122e257600080fd5b6122f3836020830160208801611ed4565b979650505050505050565b7f646174613a696d6167652f7376672b786d6c3b6261736536342c00000000000081526000825161233681601a850160208701611ed4565b91909101601a0192915050565b60008351612355818460208801611ed4565b600b60fa1b9083019081528351612373816001840160208801611ed4565b01600101949350505050565b634e487b7160e01b600052601160045260246000fd5b808201808211156105555761055561237f565b818103818111156105555761055561237f565b6000601160f91b80835284516123d8816001860160208901611ed4565b62111d1160e91b60019185019182015284516123fb816004840160208901611ed4565b016004810191909152600501949350505050565b601160f91b8152825160009061242c816001850160208801611ed4565b61111d60f11b600191840191820152835161244e816003840160208801611ed4565b01600301949350505050565b607b60f81b815260008251612476816001850160208701611ed4565b607d60f81b6001939091019283015250600201919050565b605b60f81b8152600082516124aa816001850160208701611ed4565b605d60f81b6001939091019283015250600201919050565b600084516124d4818460208901611ed4565b8451908301906124e8818360208901611ed4565b84519101906124fb818360208801611ed4565b019594505050505056fe68747470733a2f2f6c6963656e73657465726d732e63727970746f70756e6b732e6170702f3c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d2223363641363730222f3ea2646970667358221220ec69e097faa40b1dd7edff68a2f5c690527e70894098594d1c74088f56d40ba064736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000a6fa31f5fc51c1640aac76866750000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb000000000000000000000000b7f7f6c52f2e2fdb1963eab30438024864c313f600000000000000000000000016f5a35647d6f03d5d3da7b35409d65ba03af3b2
-----Decoded View---------------
Arg [0] : stashFactory (address): 0x000000000000A6fA31F5fC51c1640aAc76866750
Arg [1] : cryptoPunks (address): 0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB
Arg [2] : legacyWrapper (address): 0xb7F7F6C52F2e2fdb1963Eab30438024864c313F6
Arg [3] : _punksMetadata (address): 0x16F5A35647D6F03D5D3da7b35409D65ba03aF3B2
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000000000000000a6fa31f5fc51c1640aac76866750
Arg [1] : 000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb
Arg [2] : 000000000000000000000000b7f7f6c52f2e2fdb1963eab30438024864c313f6
Arg [3] : 00000000000000000000000016f5a35647d6f03d5d3da7b35409d65ba03af3b2
Deployed Bytecode Sourcemap
582:6502:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14979:380:1;;;;;;;;;;-1:-1:-1;14979:380:1;;;;;:::i;:::-;15292:10;15157:3;15153:21;;;;15286:17;;;15311:10;15305:17;;15283:40;15331:10;15325:17;;;15280:63;;14979:380;;;;470:14:13;;463:22;445:41;;433:2;418:18;14979:380:1;;;;;;;;1189:102:4;;;;;;;;;;-1:-1:-1;1260:24:4;;;;;;;;;;;;-1:-1:-1;;;1260:24:4;;;;1189:102;;;;;;;:::i;5579:131::-;;;;;;;;;;-1:-1:-1;5579:131:4;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1705:32:13;;;1687:51;;1675:2;1660:18;5579:131:4;1541:203:13;8099:532:1;;;;;;;;;;-1:-1:-1;8099:532:1;;;;;:::i;:::-;;:::i;8925:119::-;;;;;;:::i;:::-;;:::i;:::-;;6965:117:4;;;;;;;;;;;;;:::i;:::-;;;2400:25:13;;;2388:2;2373:18;6965:117:4;2254:177:13;10748:3001:1;;;;;;:::i;:::-;;:::i;13820:198::-;;;;;;:::i;:::-;;:::i;570:44:5:-;;;;;;;;;;;;;;;6957:332:1;;;;;;;;;;-1:-1:-1;6957:332:1;;;;;:::i;:::-;;:::i;7433:533::-;;;;;;;;;;-1:-1:-1;7433:533:1;;;;;:::i;:::-;;:::i;6048:549:4:-;;;;;;;;;;-1:-1:-1;6048:549:4;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;2163:380::-;;;;;;;;;;-1:-1:-1;2163:380:4;;;;;:::i;:::-;;:::i;1297:101::-;;;;;;;;;;-1:-1:-1;1370:21:4;;;;;;;;;;;;-1:-1:-1;;;1370:21:4;;;;1297:101;;2816:524;;;;;;;;;;-1:-1:-1;2816:524:4;;;;;:::i;:::-;;:::i;3535:151::-;;;;;;;;;;-1:-1:-1;3535:151:4;;;;;:::i;:::-;;:::i;4394:365::-;;;;;;;;;;-1:-1:-1;4394:365:4;;;;;:::i;:::-;;:::i;9667:726:1:-;;;;;;;;;;-1:-1:-1;9667:726:1;;;;;:::i;:::-;;:::i;14521:249::-;;;;;;:::i;:::-;;:::i;1535:373:4:-;;;;;;;;;;-1:-1:-1;1535:373:4;;;;;:::i;:::-;;:::i;5274:167::-;;;;;;;;;;-1:-1:-1;5274:167:4;;;;;:::i;:::-;;:::i;1404:125::-;;;;;;;;;;;;;:::i;3899:295::-;;;;;;;;;;-1:-1:-1;3899:295:4;;;;;:::i;:::-;;:::i;9135:392:1:-;;;;;;;;;;-1:-1:-1;9135:392:1;;;;;:::i;:::-;9355:4;9348:22;9396:31;9390:4;9383:45;9255:11;9441:19;9505:4;9499;9489:21;9483:28;;9135:392;5579:131:4;5668:35;;-1:-1:-1;;;5668:35:4;;-1:-1:-1;;;;;1705:32:13;;;5668:35:4;;;1687:51:13;5642:7:4;;5668:13;:29;;;;;;1660:18:13;;5668:35:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5661:42;5579:131;-1:-1:-1;;5579:131:4:o;8099:532:1:-;8161:14;8266:2;8260:4;8253:16;-1:-1:-1;;;8289:4:1;8282:38;8386:4;8380;8370:21;8366:2;8362:30;8358:2;8354:39;8430:13;8424:20;8420:2;8416:29;8406:158;;8478:10;8472:4;8465:24;8545:4;8539;8532:18;8406:158;8597:1;8593:21;8587:28;;8099:532;-1:-1:-1;;8099:532:1:o;8925:119::-;9004:33;9013:10;9025:7;9034:2;9004:8;:33::i;:::-;8925:119;;:::o;6965:117:4:-;7037:37;;-1:-1:-1;;;7037:37:4;;7068:4;7037:37;;;1687:51:13;7011:7:4;;7037:12;-1:-1:-1;;;;;7037:22:4;;;;1660:18:13;;7037:37:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7030:44;;6965:117;:::o;10748:3001:1:-;11025:1;11169:16;;;-1:-1:-1;;;11240:8:1;11211:38;11205:4;11198:52;11316:4;11300:21;;11292:30;;11284:39;;11359:20;;-1:-1:-1;;;;;11049:25:1;;;;11093:23;;;;11405:36;;;11284:39;11544:15;;;11533:27;;11523:328;;11590:5;11580:146;;11632:10;11626:4;11619:24;11703:4;11697;11690:18;11580:146;11756:10;11750:4;11743:24;11832:4;11826;11819:18;11523:328;11925:2;11915:135;;11960:10;11954:4;11947:24;12031:4;12025;12018:18;11915:135;12153:4;12147;12140:18;12211:13;12208:1;12204:21;12198:28;12175:51;;12361:15;12351:8;12348:29;12341:4;12331:8;12328:18;12325:53;12315:288;;12434:4;12428;12418:21;12412:28;12402:183;;12481:10;12475:4;12468:24;12558:4;12552;12545:18;12402:183;12678:15;12675:55;;;12726:1;12710:13;12707:1;12703:21;12696:32;12675:55;12842:13;;;12821:35;12799:58;;-1:-1:-1;12975:4:1;12969;12959:21;;;13025:22;;-1:-1:-1;;13021:30:1;12997:55;;-1:-1:-1;13143:16:1;;;13197:21;13266:20;;13049:1;13262:28;13342:20;13317:46;;13307:192;;13400:10;13394:4;13387:24;13476:4;13470;13463:18;13307:192;13516:42;;13687:2;13683;13677:4;13650:25;13644:4;13632:10;13627:63;13709:33;10748:3001;;;:::o;13820:198::-;13917:26;13930:4;13936:2;13940;13917:12;:26::i;:::-;36962:14;;13953:58;;;13971:40;13994:4;14000:2;14004;13971:40;;;;;;;;;;;;:22;:40::i;6957:332::-;7015:14;7050:12;7059:2;7050:8;:12::i;:::-;7041:21;;7148:6;7138:135;;7187:10;7181:4;7174:24;7254:4;7248;7241:18;7138:135;6957:332;;;:::o;7433:533::-;7496:14;7656:5;7646:143;;7694:10;7688:4;7681:24;7770:4;7764;7757:18;7646:143;-1:-1:-1;;;7809:4:1;7802:38;7866:5;7860:4;7853:19;7929:20;7921:4;7915;7905:21;7899:28;7895:55;7885:65;;7433:533;;;:::o;6048:549:4:-;6109:16;6161:19;6194:22;6219:16;6229:5;6219:9;:16::i;:::-;6194:41;;6249:25;6291:14;6277:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6277:29:4;;6249:57;;6326:9;6321:231;6356:14;6341:11;:29;6321:231;;6395:18;6416:11;6425:1;6416:8;:11::i;:::-;6395:32;;6463:5;-1:-1:-1;;;;;6449:19:4;:10;-1:-1:-1;;;;;6449:19:4;;6445:93;;6518:1;6492:8;6501:13;;;;;;6492:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;6445:93;-1:-1:-1;6372:3:4;;6321:231;;;-1:-1:-1;6572:8:4;6048:549;-1:-1:-1;;;;6048:549:4:o;2163:380::-;2235:41;;-1:-1:-1;;;2235:41:4;;2265:10;2235:41;;;1687:51:13;2219:13:4;;2235;-1:-1:-1;;;;;2235:29:4;;;;1660:18:13;;2235:41:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2219:57;-1:-1:-1;2340:18:4;;2287:12;2382:9;;;2378:77;;2407:37;;-1:-1:-1;;;2407:37:4;;2433:10;2407:37;;;1687:51:13;2407:13:4;-1:-1:-1;;;;;2407:25:4;;;;1660:18:13;;2407:37:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;2378:77;2465:33;;-1:-1:-1;;;2465:33:4;;;;;2400:25:13;;;-1:-1:-1;;;;;2465:22:4;;;;;2373:18:13;;2465:33:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2508:28;2514:10;2526:9;2508:5;:28::i;2816:524::-;2906:41;;-1:-1:-1;;;2906:41:4;;2936:10;2906:41;;;1687:51:13;2890:13:4;;2906;-1:-1:-1;;;;;2906:29:4;;;;1660:18:13;;2906:41:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2890:57;-1:-1:-1;3011:18:4;;2958:12;3053:9;;;3049:77;;3078:37;;-1:-1:-1;;;3078:37:4;;3104:10;3078:37;;;1687:51:13;3078:13:4;-1:-1:-1;;;;;3078:25:4;;;;1660:18:13;;3078:37:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;3049:77;3141:9;3136:198;3156:22;;;3136:198;;;3199:17;3219:11;;3231:1;3219:14;;;;;;;:::i;:::-;;;;;;;3199:34;;3255:5;-1:-1:-1;;;;;3248:22:4;;3271:9;3248:33;;;;;;;;;;;;;2400:25:13;;2388:2;2373:18;;2254:177;3248:33:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3295:28;3301:10;3313:9;3295:5;:28::i;:::-;-1:-1:-1;3180:3:4;;3136:198;;;;2880:460;;2816:524;;:::o;3535:151::-;3593:28;3599:10;3611:9;3593:5;:28::i;:::-;3631:48;;-1:-1:-1;;;3631:48:4;;3657:10;3631:48;;;7025:51:13;7092:18;;;7085:34;;;3631:12:4;-1:-1:-1;;;;;3631:25:4;;;;6998:18:13;;3631:48:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4394:365;4485:9;4480:273;4500:22;;;4480:273;;;4543:17;4563:11;;4575:1;4563:14;;;;;;;:::i;:::-;4591:65;;-1:-1:-1;;;4591:65:4;;4619:10;4591:65;;;7370:34:13;4639:4:4;7420:18:13;;;7413:43;4563:14:4;;;;;;;;;7472:18:13;;;7465:34;;;4563:14:4;-1:-1:-1;;;;;;;4591:14:4;:27;;;;7305:18:13;;4591:65:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4670:30:4;;-1:-1:-1;;;4670:30:4;;;;;2400:25:13;;;4670:14:4;-1:-1:-1;;;;;4670:19:4;;-1:-1:-1;4670:19:4;;-1:-1:-1;2373:18:13;;4670:30:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4714:28;4720:10;4732:9;4714:5;:28::i;:::-;-1:-1:-1;4524:3:4;;4480:273;;9667:726:1;9882:10;9875:18;9868:26;9854:40;;9991:8;9985:4;9978:22;10026:31;10020:4;10013:45;10084:8;10078:4;10071:22;10136:10;10129:4;10123;10113:21;10106:41;10221:10;10215:4;10208:24;10366:8;10362:2;10358:17;10354:2;10350:26;10340:8;10305:33;10299:4;10293;10288:89;9667:726;;:::o;14521:249::-;14667:26;14680:4;14686:2;14690;14667:12;:26::i;:::-;36962:14;;14703:60;;;14721:42;14744:4;14750:2;14754;14758:4;;14721:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14721:22:1;;-1:-1:-1;;;14721:42:1:i;1535:373:4:-;1600:13;1739:5;1728:7;:16;1724:73;;1767:19;;-1:-1:-1;;;1767:19:4;;;;;;;;;;;1724:73;1860:40;1880:18;1890:7;1880:9;:18::i;:::-;1860:13;:40::i;:::-;1813:88;;;;;;;;:::i;:::-;;;;;;;;;;;;;1806:95;;1535:373;;;:::o;5274:167::-;15751:11:1;15840:16;;;-1:-1:-1;;;15876:4:1;15869:38;15990:4;15974:21;;15966:30;;15958:39;;15952:46;15948:2;15944:55;15937:63;5332:44:4;;5363:13;;-1:-1:-1;;;5363:13:4;;;;;;;;;;;1404:125;1451:13;1476:46;;;;;;;;;;;;;;;;;;;1404:125;:::o;3899:295::-;3980:9;3975:213;3995:22;;;3975:213;;;4038:17;4058:11;;4070:1;4058:14;;;;;;;:::i;:::-;;;;;;;4038:34;;4087:28;4093:10;4105:9;4087:5;:28::i;:::-;4129:48;;-1:-1:-1;;;4129:48:4;;4155:10;4129:48;;;7025:51:13;7092:18;;;7085:34;;;4129:12:4;-1:-1:-1;;;;;4129:25:4;;;;6998:18:13;;4129:48:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4019:3:4;;;;;-1:-1:-1;3975:213:4;;-1:-1:-1;;3975:213:4;27519:1442:1;27702:1;27698:6;27694:2;27690:15;27749:7;27733:14;27729:28;27718:39;;27796:2;27780:14;27776:23;27770:29;;27869:2;27863:4;27856:16;27927:2;-1:-1:-1;;;27898:32:1;27892:4;27885:46;27997:4;27991;27981:21;27977:2;27973:30;27969:2;27965:39;28056:13;28050:20;28034:14;28030:41;28017:54;;28145:5;28135:134;;28183:10;28177:4;28170:24;28250:4;28244;28237:18;28135:134;28452:5;28448:2;28445:13;28440:2;28433:10;28430:29;28420:280;;28492:5;28486:4;28479:19;28547:4;28541;28531:21;28525:28;28515:171;;28590:10;28584:4;28577:24;28663:4;28657;28650:18;28515:171;28794:1;28790:21;28783:38;;;28942:2;28813:7;28926:5;28899:25;28893:4;28881:10;28876:69;;27519:1442;;;:::o;37183:1370::-;37420:4;37414:11;37470:10;37503:24;37500:1;37493:35;37562:8;37555:4;37552:1;37548:12;37541:30;37670:4;37666:2;37662:13;37658:2;37654:22;37647:4;37644:1;37640:12;37633:44;37711:2;37704:4;37701:1;37697:12;37690:24;37748:4;37741;37738:1;37734:12;37727:26;37781:4;37775:11;37820:1;37813:4;37810:1;37806:12;37799:23;37838:1;37835:71;;;37901:1;37894:4;37891:1;37887:12;37884:1;37877:4;37871;37867:15;37864:1;37857:5;37846:57;37842:62;37835:71;38022:4;38019:1;38012:4;38009:1;38005:12;37998:4;37995:1;37991:12;37988:1;37984:2;37977:5;37972:55;37962:313;;38050:16;38047:214;;;38178:16;38172:4;38169:1;38154:41;38226:16;38223:1;38216:27;38047:214;37962:313;38371:24;38366:3;38362:34;38358:1;38352:8;38349:48;38339:198;;38430:10;38424:4;38417:24;38518:4;38512;38505:18;38339:198;;;37183:1370;;;;:::o;16152:323::-;16213:14;16305:16;;;-1:-1:-1;;;16341:4:1;16334:38;16449:4;16433:21;;16425:30;;16417:39;16411:46;-1:-1:-1;;;;;16395:64:1;;16152:323::o;19724:1682::-;-1:-1:-1;;;;;19952:20:1;;;;;20036:135;;20081:10;20075:4;20068:24;20152:4;20146;20139:18;20036:135;20237:2;20231:4;20224:16;-1:-1:-1;;;20260:4:1;20253:38;20357:4;20351;20341:21;20337:2;20333:30;20329:2;20325:39;20406:13;20400:20;20495:15;20491:2;20487:24;20484:146;;;20543:10;20537:4;20530:24;20611:4;20605;20598:18;20484:146;20703:23;;20681:46;;20816:4;20809:16;;;20877:4;20871;20861:21;20928:18;;20948:1;20924:26;21000:20;20977:44;;20967:190;;21058:10;21052:4;21045:24;21134:4;21128;21121:18;20967:190;21174:38;;21338:2;21334;21331:1;21304:25;21331:1;21286:10;21281:60;8925:119;;:::o;22812:2127::-;22878:13;22894:11;22902:2;22894:7;:11::i;:::-;22878:27;;-1:-1:-1;23160:4:1;23153:16;;;-1:-1:-1;;;;;23080:20:1;;;-1:-1:-1;;;23195:32:1;;23189:4;23182:46;23294:4;23278:21;;;23270:30;;23262:39;;23337:20;;23080;;23460:33;;;;23557:134;;23605:10;23599:4;23592:24;23672:4;23666;23659:18;23557:134;23785:5;23779:4;23772:19;23844:13;23841:1;23837:21;23831:28;24076:15;24072:2;24069:23;24061:5;24057:2;24054:13;24051:42;24046:2;24039:10;24036:58;24026:293;;24150:4;24144;24134:21;24128:28;24118:183;;24197:10;24191:4;24184:24;24274:4;24268;24261:18;24118:183;24394:15;24391:55;;;24442:1;24426:13;24423:1;24419:21;24412:32;24391:55;-1:-1:-1;24527:27:1;;24505:50;;24670:4;24664;24654:21;24716:18;;-1:-1:-1;;24712:26:1;24692:47;;24868:2;-1:-1:-1;24548:5:1;24831:25;-1:-1:-1;24813:10:1;24808:63;10748:3001;;;:::o;954:819:5:-;1108:34;;-1:-1:-1;;;1108:34:5;;8140:6:13;8128:19;;1108:34:5;;;8110:38:13;1013:13:5;;1064:7;;1038:16;;1108:10;-1:-1:-1;;;;;1108:23:5;;;;8083:18:13;;1108:34:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1108:34:5;;;;;;;;;;;;:::i;:::-;1082:60;;1164:30;1180:9;1191:2;1164:15;:30::i;:::-;1152:42;;1217:141;1247:33;1263:9;1274:1;1277:2;1247:15;:33::i;:::-;1282:66;1299:16;;;;;;;;;;;;;;;;;1317:30;1333:9;1344:2;1317:15;:30::i;:::-;1282:16;:66::i;1217:141::-;1396:36;;-1:-1:-1;;;1396:36:5;;8140:6:13;8128:19;;1396:36:5;;;8110:38:13;1205:153:5;;-1:-1:-1;1369:24:5;;-1:-1:-1;;;;;1396:10:5;:25;;;;8083:18:13;;1396:36:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1396:36:5;;;;;;;;;;;;:::i;:::-;1369:63;;1456:32;1477:10;1456:20;:32::i;:::-;1443:45;;1505:261;1561:100;;;;;;;;;;;;;;-1:-1:-1;;;1561:100:5;;;1628:31;1648:9;1628:13;:31::i;:::-;1584:76;;;;;;;;:::i;:::-;;;;;;;;;;;;;1561:13;:100::i;:::-;1700:42;;;;;;;;;;;;;;-1:-1:-1;;;1700:42:5;;;1731:10;1700:16;:42::i;:::-;1530:226;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1505:11;:261::i;:::-;1498:268;954:819;-1:-1:-1;;;;;954:819:5:o;3414:132:2:-;3472:20;3513:26;3520:4;3526:5;3533;3513:6;:26::i;31638:194:3:-;31738:20;31783:42;31789:7;31798:5;-1:-1:-1;;31783:5:3;:42::i;:::-;31774:51;31638:194;-1:-1:-1;;;31638:194:3:o;30204:1307::-;30317:20;30446:7;30440:14;30495:3;30480:13;30477:22;30467:58;;30510:13;30503:20;;30467:58;30566:5;30551:13;30548:24;30538:62;;30585:13;30576:22;;30538:62;;30626:3;30619:5;30616:14;30613:882;;;-1:-1:-1;30665:4:3;30659:11;30707:15;;;30739:28;;;30795:19;;;;-1:-1:-1;;30844:4:3;30954:23;;30950:31;;30935:237;31040:15;;;31034:22;31018:14;;;31011:46;31083:9;;31132:22;30935:237;31132:22;-1:-1:-1;31288:1:3;31250:36;;;31266:4;31250:36;31243:47;31470:4;31452:23;;;31448:31;31436:44;;31430:4;31423:58;30204:1307;;;;;:::o;36854:1365::-;37100:4;37094:11;37133:8;;-1:-1:-1;;37062:9:3;37241:4;37228:18;;37224:26;;37209:210;37305:9;;;37299:16;37283:14;;;37276:40;37338:9;;37383:22;37209:210;37383:22;37213:39;37453:1;37447:8;37494:7;37486:6;37482:20;37609:1;37602:4;37593:7;37589:18;37585:26;37570:210;37666:9;;;37660:16;37644:14;;;37637:40;37699:9;;37744:22;37570:210;37744:22;-1:-1:-1;;37969:1:3;37812:21;;37858:35;;;37874:4;37858:35;;37956:15;;;;38018:27;;38183:15;;38179:23;38173:4;38166:37;37866:6;36854:1365;-1:-1:-1;;36854:1365:3:o;2011:2047:5:-;2090:20;2122:32;2157:41;2173:10;2185:12;;;;;;;;;;;;;-1:-1:-1;;;2185:12:5;;;2157:15;:41::i;:::-;2122:76;;2208:16;2233;2250:1;2233:19;;;;;;;;:::i;:::-;;;;;;;2254:1;2227:29;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;2227:29:5;;-1:-1:-1;2349:12:5;-1:-1:-1;;;2364:16:5;;;:36;;-1:-1:-1;;;;;;;;;;2384:16:5;;;2364:36;2349:51;;2410:31;2483:38;2535:7;2531:524;;;2682:23;;:27;;2708:1;2682:27;:::i;:::-;2669:41;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2651:59;;2749:41;2765:16;2782:1;2765:19;;;;;;;;:::i;:::-;;;;;;;2749:41;;;;;;;;;;;;;-1:-1:-1;;;2749:41:5;;;:15;:41::i;:::-;2724:66;;2825:50;;;;;;;;;;;;;;-1:-1:-1;;;2825:50:5;;;2849:22;2872:1;2849:25;;;;;;;;:::i;:::-;;;;;;;2825:15;:50::i;:::-;2804:15;2820:1;2804:18;;;;;;;;:::i;:::-;;;;;;:71;;;;2531:524;;;2937:23;;:27;;2963:1;2937:27;:::i;:::-;2924:41;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2906:59;;3000:44;;;;;;;;;;;;;;-1:-1:-1;;;3000:44:5;;;3024:16;3041:1;3024:19;;;;;;;;:::i;3000:44::-;2979:15;2995:1;2979:18;;;;;;;;:::i;:::-;;;;;;:65;;;;2531:524;3152:13;3194:1;3168:16;:23;:27;;;;:::i;:::-;3322:33;;;;;;;;;;;;-1:-1:-1;;;3322:33:5;;;;3152:43;;-1:-1:-1;3462:1:5;3445:143;3469:16;:23;3465:1;:27;3445:143;;;3534:43;3550:5;3557:16;3574:1;3557:19;;;;;;;;:::i;3534:43::-;3513:15;3529:1;3513:18;;;;;;;;:::i;:::-;;;;;;;;;;:64;3494:3;;3445:143;;;;3689:61;;;;;;;;;;;;;;-1:-1:-1;;;3689:61:5;;;3724:25;3743:5;3724:18;:25::i;:::-;3689:15;:61::i;:::-;3646:15;3662:16;:23;3646:40;;;;;;;;:::i;:::-;;;;;;:104;;;;3765:7;3761:186;;;3881:55;;;;;;;;;;;;;;-1:-1:-1;;;3881:55:5;;;3910:22;3933:1;3910:25;;;;;;;;:::i;3881:55::-;3834:15;3850:16;:23;3876:1;3850:27;;;;:::i;:::-;3834:44;;;;;;;;:::i;:::-;;;;;;:102;;;;3761:186;4022:29;4035:15;4022:12;:29::i;:::-;4015:36;2011:2047;-1:-1:-1;;;;;;;;;2011:2047:5:o;1099:190:0:-;1181:13;1232:17;:4;:15;:17::i;:::-;1258:18;:5;:16;:18::i;:::-;1213:69;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1206:76;;1099:190;;;;:::o;1667:180::-;1755:13;1806:17;:4;:15;:17::i;:::-;1831:8;1787:53;;;;;;;;;:::i;361:129::-;421:13;472:5;453:30;;;;;;;;:::i;722:2557:2:-;835:20;961:4;955:11;983:10;980:2283;;;1183:1;1179;1167:10;1163:18;1159:26;1156:1;1152:34;1294:4;1288:11;1278:21;;1664:34;1658:4;1651:48;1791:6;1780:8;1773:16;1769:29;1733:34;1729:70;1723:4;1716:84;1906:4;1898:6;1894:17;1948:13;1943:3;1939:23;2038:623;2090:1;2084:4;2080:12;2072:20;;2152:4;2146:11;2292:4;2284:5;2280:2;2276:14;2272:25;2266:32;2263:1;2255:44;2357:4;2349:5;2345:2;2341:14;2337:25;2331:32;2328:1;2320:44;2421:4;2413:5;2410:1;2406:13;2402:24;2396:31;2393:1;2385:43;2477:4;2470:5;2466:16;2460:23;2457:1;2449:35;;2523:4;2517:11;2512:3;2505:24;2567:1;2562:3;2558:11;2551:18;;2628:3;2623;2620:12;2038:623;2610:33;2700:4;2691:14;2685:4;2678:28;-1:-1:-1;;;2845:1:2;2829:18;;2826:1;2822:26;2956:11;;;2949:37;;;;3134:1;3075:17;;3068:25;3064:33;;;3121:11;;;;3114:22;3206:21;;3191:37;;980:2283;;722:2557;;;;;:::o;34618:2085:3:-;34728:22;34766:24;34793:29;34803:7;34812:9;34793;:29::i;:::-;34766:56;;34911:4;34907:9;34958:4;34949:7;34945:18;35035:1;35025:7;35019:14;35015:22;35012:1;35008:30;34998:8;34994:45;35085:7;35079:14;35075:1;35063:10;35059:18;35052:42;35143:1;35133:7;35127:14;35123:22;35114:7;35107:39;35176:1;35190:1311;35239:8;35233:15;35282:4;35272:8;35265:22;35324:9;35317:5;35314:20;35304:1015;;35379:4;35373:11;35437:9;35430:5;35426:21;35484:13;35475:7;35468:30;35637:1;35630:4;35615:13;35611:24;35607:32;35592:271;35707:23;;;35703:31;;35697:38;35680:15;;;35673:63;35766:9;;35819:22;35592:271;35819:22;-1:-1:-1;35989:1:3;35949:38;;;35966:4;35949:38;35942:49;36185:4;36166:24;36162:32;;36149:46;;36143:4;36136:60;36276:25;;35304:1015;36360:16;;36420:4;36406:19;;;;;36349:28;;-1:-1:-1;36452:24:3;;;35190:1311;36442:45;35194:2;;;;36524:7;36514:17;;36560:9;36554:16;36544:143;;36613:4;36604:7;36600:18;36590:28;;36670:1;36660:7;36654:14;36650:22;36642:6;36635:38;36544:143;34884:1813;34618:2085;;;;:::o;4131:227:5:-;4221:13;4253:98;4279:34;;;;;;;;;;;;;;-1:-1:-1;;;4279:34:5;;;4307:5;4279:13;:34::i;:::-;4320:29;;;;;;;;;;;;;;-1:-1:-1;;;4320:29:5;;;4343:5;4320:13;:29::i;1645:1641:3:-;1701:17;2146:4;2139;2133:11;2129:22;2122:29;;2245:4;2240:3;2236:14;2230:4;2223:28;2326:1;2321:3;2314:14;2427:3;2457:1;2453:6;2666:5;2648:402;2704:11;;;;2885:2;2899;2889:13;;2881:22;2704:11;2868:36;2991:2;2981:13;;3011:25;2648:402;3011:25;-1:-1:-1;;3078:13:3;;;-1:-1:-1;;3191:14:3;;;3251:19;;;3191:14;1645:1641;-1:-1:-1;1645:1641:3:o;2843:128:0:-;2907:13;2939:25;2945:18;2956:6;2945:10;:18::i;:::-;2939:5;:25::i;45660:128:3:-;45720:20;45761;45772:1;45775:5;45761:10;:20::i;31939:2575::-;32050:23;32182:7;32176:14;32229:6;32223:13;32277;32263:12;32260:31;32250:2248;;32335:4;32326:7;32322:18;32311:29;;32379:4;32371:6;32367:17;32357:27;;32428:4;32421;32415:11;32411:22;32401:32;;32471:7;32571:1;32556:12;32540:13;32531:7;32527:27;32523:46;32519:54;32599:1;32644:4;32630:12;32627:22;32617:74;;-1:-1:-1;32658:31:3;;;32617:74;32752:4;32738:12;32734:23;32728:4;32724:34;32721:1;32717:42;32791:6;32785:13;32815:1218;32864:7;32858:14;33042:1;33039;33035:9;33032:1;33028:17;33018:879;;33076:1;33073:326;;;33155:1;33140:12;33131:7;33121:32;33118:39;33108:265;;33217:1;33208:7;33204:15;33193:26;;33274:16;33265:7;33262:29;33252:50;;33295:5;;;33252:50;33335:8;32815:1218;;33108:265;33486:26;;;33471:42;;33665:26;;;;33560:4;33548:17;;;;33716:159;;;;33784:16;33775:7;33772:29;33762:50;;33805:5;;;33716:159;33018:879;33942:1;33933:7;33929:15;33918:26;;33987:16;33978:7;33975:29;32815:1218;33965:50;32815:1218;-1:-1:-1;;34169:4:3;34163:11;;-1:-1:-1;;34262:33:3;;;;34259:1;34255:41;34240:57;;34289:4;34463:20;;;34450:34;;-1:-1:-1;;;32250:2248:3;;;31939:2575;;;;:::o;4171:124:0:-;4238:13;4270:18;4276:6;4270:18;;;;;;;;;;;;;-1:-1:-1;;;4270:18:0;;;:5;:18::i;694:128::-;753:13;804:5;785:30;;;;;;;;:::i;43188:2391:3:-;43414:8;;43456:4;43450:11;43463:4;43446:22;;43407:16;;43481:111;;;;43534:2;43526:6;43518:19;43571:6;43568:1;43564:14;43554:24;;43481:111;43845:58;43839:4;43832:72;43978:30;44021:1143;44041:3;44038:1;44035:10;44021:1143;;44080:1;44077;44073:9;44068:14;;44122:4;44118:1;44112:8;44108:19;44160:4;44157:1;44154:11;44144:461;;44214:1;44210;44207;44203:9;44199:17;44189:226;;44309:1;44301:6;44293:18;44358:1;44350:6;44346:14;44336:24;;44385:8;44021:1143;;44189:226;44452:4;44444:6;44436:21;44511:1;44507;44499:6;44495:14;44487:26;44556:1;44548:6;44544:14;44534:24;;44579:8;44021:1143;;44144:461;44647:6;44643:1;44640;44636:9;44632:22;44622:382;;44765:1;44762;44758:9;44752:16;44746:4;44738:31;44831:2;44828:1;44824:10;44818:17;44812:4;44804:32;44892:4;44886:11;44878:6;44871:27;44955:1;44947:6;44943:14;44933:24;;44978:8;44021:1143;;44622:382;45037:4;45029:6;45021:21;45105:1;45102;45098:9;45092:16;45088:1;45080:6;45076:14;45068:41;;45148:1;45140:6;45136:14;45126:24;;44021:1143;;;44025:2;;45180:15;45177:111;;;45230:2;45222:6;45214:19;45264:1;45260:14;45177:111;45345:1;45332:15;;45414:4;45408:11;;-1:-1:-1;;45447:28:3;;;;45432:44;;45469:4;45523:15;;;45510:29;;45408:11;43188:2391;-1:-1:-1;;43188:2391:3:o;4873:371:0:-;4960:13;4989:6;:13;5006:1;4989:18;4985:58;;-1:-1:-1;5023:9:0;;;;;;;;;-1:-1:-1;5023:9:0;;;;4985:58;5052:20;5075:6;5082:1;5075:9;;;;;;;;:::i;:::-;;;;;;;5052:32;;5099:9;5111:1;5099:13;;5094:121;5118:6;:13;5114:1;:17;5094:121;;;5175:6;5183:9;5194:6;5201:1;5194:9;;;;;;;;:::i;:::-;;;;;;;5161:43;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;5161:43:0;;;;;;;;;;-1:-1:-1;5133:3:0;;5094:121;;14:286:13;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:13;;209:43;;199:71;;266:1;263;256:12;497:250;582:1;592:113;606:6;603:1;600:13;592:113;;;682:11;;;676:18;663:11;;;656:39;628:2;621:10;592:113;;;-1:-1:-1;;739:1:13;721:16;;714:27;497:250::o;752:396::-;901:2;890:9;883:21;864:4;933:6;927:13;976:6;971:2;960:9;956:18;949:34;992:79;1064:6;1059:2;1048:9;1044:18;1039:2;1031:6;1027:15;992:79;:::i;:::-;1132:2;1111:15;-1:-1:-1;;1107:29:13;1092:45;;;;1139:2;1088:54;;752:396;-1:-1:-1;;752:396:13:o;1153:131::-;-1:-1:-1;;;;;1228:31:13;;1218:42;;1208:70;;1274:1;1271;1264:12;1208:70;1153:131;:::o;1289:247::-;1348:6;1401:2;1389:9;1380:7;1376:23;1372:32;1369:52;;;1417:1;1414;1407:12;1369:52;1456:9;1443:23;1475:31;1500:5;1475:31;:::i;1749:180::-;1808:6;1861:2;1849:9;1840:7;1836:23;1832:32;1829:52;;;1877:1;1874;1867:12;1829:52;-1:-1:-1;1900:23:13;;1749:180;-1:-1:-1;1749:180:13:o;1934:315::-;2002:6;2010;2063:2;2051:9;2042:7;2038:23;2034:32;2031:52;;;2079:1;2076;2069:12;2031:52;2118:9;2105:23;2137:31;2162:5;2137:31;:::i;:::-;2187:5;2239:2;2224:18;;;;2211:32;;-1:-1:-1;;;1934:315:13:o;2436:456::-;2513:6;2521;2529;2582:2;2570:9;2561:7;2557:23;2553:32;2550:52;;;2598:1;2595;2588:12;2550:52;2637:9;2624:23;2656:31;2681:5;2656:31;:::i;:::-;2706:5;-1:-1:-1;2763:2:13;2748:18;;2735:32;2776:33;2735:32;2776:33;:::i;:::-;2436:456;;2828:7;;-1:-1:-1;;;2882:2:13;2867:18;;;;2854:32;;2436:456::o;3130:632::-;3301:2;3353:21;;;3423:13;;3326:18;;;3445:22;;;3272:4;;3301:2;3524:15;;;;3498:2;3483:18;;;3272:4;3567:169;3581:6;3578:1;3575:13;3567:169;;;3642:13;;3630:26;;3711:15;;;;3676:12;;;;3603:1;3596:9;3567:169;;;-1:-1:-1;3753:3:13;;3130:632;-1:-1:-1;;;;;;3130:632:13:o;3767:615::-;3853:6;3861;3914:2;3902:9;3893:7;3889:23;3885:32;3882:52;;;3930:1;3927;3920:12;3882:52;3970:9;3957:23;3999:18;4040:2;4032:6;4029:14;4026:34;;;4056:1;4053;4046:12;4026:34;4094:6;4083:9;4079:22;4069:32;;4139:7;4132:4;4128:2;4124:13;4120:27;4110:55;;4161:1;4158;4151:12;4110:55;4201:2;4188:16;4227:2;4219:6;4216:14;4213:34;;;4243:1;4240;4233:12;4213:34;4296:7;4291:2;4281:6;4278:1;4274:14;4270:2;4266:23;4262:32;4259:45;4256:65;;;4317:1;4314;4307:12;4256:65;4348:2;4340:11;;;;;4370:6;;-1:-1:-1;3767:615:13;;-1:-1:-1;;;;3767:615:13:o;4387:416::-;4452:6;4460;4513:2;4501:9;4492:7;4488:23;4484:32;4481:52;;;4529:1;4526;4519:12;4481:52;4568:9;4555:23;4587:31;4612:5;4587:31;:::i;:::-;4637:5;-1:-1:-1;4694:2:13;4679:18;;4666:32;4736:15;;4729:23;4717:36;;4707:64;;4767:1;4764;4757:12;4707:64;4790:7;4780:17;;;4387:416;;;;;:::o;4808:936::-;4905:6;4913;4921;4929;4937;4990:3;4978:9;4969:7;4965:23;4961:33;4958:53;;;5007:1;5004;4997:12;4958:53;5046:9;5033:23;5065:31;5090:5;5065:31;:::i;:::-;5115:5;-1:-1:-1;5172:2:13;5157:18;;5144:32;5185:33;5144:32;5185:33;:::i;:::-;5237:7;-1:-1:-1;5291:2:13;5276:18;;5263:32;;-1:-1:-1;5346:2:13;5331:18;;5318:32;5369:18;5399:14;;;5396:34;;;5426:1;5423;5416:12;5396:34;5464:6;5453:9;5449:22;5439:32;;5509:7;5502:4;5498:2;5494:13;5490:27;5480:55;;5531:1;5528;5521:12;5480:55;5571:2;5558:16;5597:2;5589:6;5586:14;5583:34;;;5613:1;5610;5603:12;5583:34;5658:7;5653:2;5644:6;5640:2;5636:15;5632:24;5629:37;5626:57;;;5679:1;5676;5669:12;5626:57;4808:936;;;;-1:-1:-1;4808:936:13;;-1:-1:-1;5710:2:13;5702:11;;5732:6;4808:936;-1:-1:-1;;;4808:936:13:o;5749:388::-;5817:6;5825;5878:2;5866:9;5857:7;5853:23;5849:32;5846:52;;;5894:1;5891;5884:12;5846:52;5933:9;5920:23;5952:31;5977:5;5952:31;:::i;:::-;6002:5;-1:-1:-1;6059:2:13;6044:18;;6031:32;6072:33;6031:32;6072:33;:::i;6142:251::-;6212:6;6265:2;6253:9;6244:7;6240:23;6236:32;6233:52;;;6281:1;6278;6271:12;6233:52;6313:9;6307:16;6332:31;6357:5;6332:31;:::i;6398:184::-;6468:6;6521:2;6509:9;6500:7;6496:23;6492:32;6489:52;;;6537:1;6534;6527:12;6489:52;-1:-1:-1;6560:16:13;;6398:184;-1:-1:-1;6398:184:13:o;6587:127::-;6648:10;6643:3;6639:20;6636:1;6629:31;6679:4;6676:1;6669:15;6703:4;6700:1;6693:15;6719:127;6780:10;6775:3;6771:20;6768:1;6761:31;6811:4;6808:1;6801:15;6835:4;6832:1;6825:15;7510:451;7762:31;7757:3;7750:44;7732:3;7823:6;7817:13;7839:75;7907:6;7902:2;7897:3;7893:12;7886:4;7878:6;7874:17;7839:75;:::i;:::-;7934:16;;;;7952:2;7930:25;;7510:451;-1:-1:-1;;7510:451:13:o;8159:897::-;8239:6;8292:2;8280:9;8271:7;8267:23;8263:32;8260:52;;;8308:1;8305;8298:12;8260:52;8341:9;8335:16;8370:18;8411:2;8403:6;8400:14;8397:34;;;8427:1;8424;8417:12;8397:34;8465:6;8454:9;8450:22;8440:32;;8510:7;8503:4;8499:2;8495:13;8491:27;8481:55;;8532:1;8529;8522:12;8481:55;8561:2;8555:9;8583:2;8579;8576:10;8573:36;;;8589:18;;:::i;:::-;8664:2;8658:9;8632:2;8718:13;;-1:-1:-1;;8714:22:13;;;8738:2;8710:31;8706:40;8694:53;;;8762:18;;;8782:22;;;8759:46;8756:72;;;8808:18;;:::i;:::-;8848:10;8844:2;8837:22;8883:2;8875:6;8868:18;8923:7;8918:2;8913;8909;8905:11;8901:20;8898:33;8895:53;;;8944:1;8941;8934:12;8895:53;8957:68;9022:2;9017;9009:6;9005:15;9000:2;8996;8992:11;8957:68;:::i;:::-;9044:6;8159:897;-1:-1:-1;;;;;;;8159:897:13:o;9061:448::-;9313:28;9308:3;9301:41;9283:3;9371:6;9365:13;9387:75;9455:6;9450:2;9445:3;9441:12;9434:4;9426:6;9422:17;9387:75;:::i;:::-;9482:16;;;;9500:2;9478:25;;9061:448;-1:-1:-1;;9061:448:13:o;9514:629::-;9783:3;9821:6;9815:13;9837:66;9896:6;9891:3;9884:4;9876:6;9872:17;9837:66;:::i;:::-;-1:-1:-1;;;9925:16:13;;;9950:18;;;9993:13;;10015:78;9993:13;10080:1;10069:13;;10062:4;10050:17;;10015:78;:::i;:::-;10113:20;10135:1;10109:28;;9514:629;-1:-1:-1;;;;9514:629:13:o;10148:127::-;10209:10;10204:3;10200:20;10197:1;10190:31;10240:4;10237:1;10230:15;10264:4;10261:1;10254:15;10280:125;10345:9;;;10366:10;;;10363:36;;;10379:18;;:::i;10410:128::-;10477:9;;;10498:11;;;10495:37;;;10512:18;;:::i;10543:934::-;10992:3;11029:2;11024:3;11020:12;11053:2;11048:3;11041:15;11085:6;11079:13;11101:74;11168:6;11164:1;11159:3;11155:11;11148:4;11140:6;11136:17;11101:74;:::i;:::-;-1:-1:-1;;;11234:1:13;11194:16;;;11226:10;;;11219:37;11281:13;;11303:75;11281:13;11365:1;11357:10;;11350:4;11338:17;;11303:75;:::i;:::-;11397:17;11438:1;11430:10;;11423:22;;;;11469:1;11461:10;;;-1:-1:-1;;;;10543:934:13:o;11482:768::-;-1:-1:-1;;;11859:25:13;;11907:13;;11841:3;;11929:74;11907:13;11992:1;11983:11;;11976:4;11964:17;;11929:74;:::i;:::-;-1:-1:-1;;;12062:1:13;12022:16;;;12054:10;;;12047:34;12106:13;;12128:75;12106:13;12190:1;12182:10;;12175:4;12163:17;;12128:75;:::i;:::-;12223:17;12242:1;12219:25;;11482:768;-1:-1:-1;;;;11482:768:13:o;12255:563::-;-1:-1:-1;;;12591:3:13;12584:16;12566:3;12629:6;12623:13;12645:74;12712:6;12708:1;12703:3;12699:11;12692:4;12684:6;12680:17;12645:74;:::i;:::-;-1:-1:-1;;;12778:1:13;12738:16;;;;12770:10;;;12763:23;-1:-1:-1;12810:1:13;12802:10;;12255:563;-1:-1:-1;12255:563:13:o;12823:::-;-1:-1:-1;;;13159:3:13;13152:16;13134:3;13197:6;13191:13;13213:74;13280:6;13276:1;13271:3;13267:11;13260:4;13252:6;13248:17;13213:74;:::i;:::-;-1:-1:-1;;;13346:1:13;13306:16;;;;13338:10;;;13331:23;-1:-1:-1;13378:1:13;13370:10;;12823:563;-1:-1:-1;12823:563:13:o;13391:703::-;13618:3;13656:6;13650:13;13672:66;13731:6;13726:3;13719:4;13711:6;13707:17;13672:66;:::i;:::-;13801:13;;13760:16;;;;13823:70;13801:13;13760:16;13870:4;13858:17;;13823:70;:::i;:::-;13960:13;;13915:20;;;13982:70;13960:13;13915:20;14029:4;14017:17;;13982:70;:::i;:::-;14068:20;;13391:703;-1:-1:-1;;;;;13391:703:13:o
Swarm Source
ipfs://ec69e097faa40b1dd7edff68a2f5c690527e70894098594d1c74088f56d40ba0
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.